/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2010 Oracle and/or its affiliates. All rights reserved. * * Oracle and Java are registered trademarks of Oracle and/or its affiliates. * Other names may be trademarks of their respective owners. * * The contents of this file are subject to the terms of either the GNU * General Public License Version 2 only ("GPL") or the Common * Development and Distribution License("CDDL") (collectively, the * "License"). You may not use this file except in compliance with the * License. You can obtain a copy of the License at * http://www.netbeans.org/cddl-gplv2.html * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the * specific language governing permissions and limitations under the * License. When distributing the software, include this License Header * Notice in each file and include the License file at * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the GPL Version 2 section of the License file that * accompanied this code. If applicable, add the following below the * License Header, with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * If you wish your version of this file to be governed by only the CDDL * or only the GPL Version 2, indicate your decision by adding * "[Contributor] elects to include this software in this distribution * under the [CDDL or GPL Version 2] license." If you do not indicate a * single choice of license, a recipient has the option to distribute * your version of this file under either the CDDL, the GPL Version 2 or * to extend the choice of license to its licensees as provided above. * However, if you add GPL Version 2 code and therefore, elected the GPL * Version 2 license, then the option applies only if the new code is * made subject to such option by the copyright holder. * * Contributor(s): * * Portions Copyrighted 2009 Sun Microsystems, Inc. */ package org.netbeans.modules.hudson.subversion; import java.io.File; import java.io.IOException; import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.netbeans.modules.hudson.api.ConnectionBuilder; import org.netbeans.modules.hudson.api.HudsonJob; import org.netbeans.modules.hudson.api.HudsonJobBuild; import org.netbeans.modules.hudson.api.Utilities; import org.netbeans.modules.hudson.spi.HudsonJobChangeItem; import org.netbeans.modules.hudson.spi.HudsonJobChangeItem.HudsonJobChangeFile; import org.netbeans.modules.hudson.spi.HudsonJobChangeItem.HudsonJobChangeFile.EditType; import org.netbeans.modules.hudson.spi.HudsonSCM; import org.netbeans.modules.hudson.spi.ProjectHudsonJobCreatorFactory.ConfigurationStatus; import org.openide.util.Exceptions; import org.openide.util.NbBundle.Messages; import org.openide.util.lookup.ServiceProvider; import org.openide.windows.OutputListener; import org.openide.xml.XMLUtil; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; /** * Lets Hudson understand things about Subversion. */ @ServiceProvider(service=HudsonSCM.class, position=100) public class HudsonSubversionSCM implements HudsonSCM { private static final Logger LOG = Logger.getLogger(HudsonSubversionSCM.class.getName()); @Messages({ "# {0} - folder", "# {1} - error message", "ERR_reading_folder=While inspecting SVN checkout in {0}: {1}" }) public @Override Configuration forFolder(File folder) { try { SvnUtils.Info info = SvnUtils.parseCheckout(folder.toURI().toURL()); if (info == null) { return null; } final String urlS = info.module.toString(); return new Configuration() { public @Override void configure(Document doc) { Element root = doc.getDocumentElement(); Element configXmlSCM = (Element) root.appendChild(doc.createElement("scm")); // NOI18N configXmlSCM.setAttribute("class", "hudson.scm.SubversionSCM"); // NOI18N Element loc = (Element) configXmlSCM.appendChild(doc.createElement("locations")). // NOI18N appendChild(doc.createElement("hudson.scm.SubversionSCM_-ModuleLocation")); // NOI18N loc.appendChild(doc.createElement("remote")).appendChild(doc.createTextNode(urlS)); // NOI18N loc.appendChild(doc.createElement("local")).appendChild(doc.createTextNode(".")); // NOI18N // HUDSON-3390 would be a more attractive alternative: configXmlSCM.appendChild(doc.createElement("useUpdate")).appendChild(doc.createTextNode("false")); // NOI18N Helper.addTrigger(doc); } public @Override ConfigurationStatus problems() { return null; } }; } catch (IOException ex) { return new Configuration() {} LOG.log(Level.WARNING, "inspecting configuration for " + folder, ex); Exceptions.printStackTrace(ex); return null; } } public @Override String translateWorkspacePath(HudsonJob job, String workspacePath, File localRoot) { try { SvnUtils.Info local = SvnUtils.parseCheckout(localRoot.toURI().toURL()); if (local == null) { return null; } int slash = workspacePath.lastIndexOf('/'); String workspaceDir = workspacePath.substring(0, slash + 1); String workspaceFile = workspacePath.substring(slash + 1); URL remoteCheckout = new URL(job.getUrl() + "ws/" + workspaceDir); // NOI18N SvnUtils.Info remote = SvnUtils.parseCheckout(remoteCheckout, job); if (remote == null) { LOG.log(Level.FINE, "no remote checkout found at {0}", remoteCheckout); return null; } // Example: // workspacePath = trunk/myprj/nbproject/build-impl.xml // workspaceDir = trunk/myprj/nbproject/ // workspaceFile = build-impl.xml // remoteCheckout = http://my.build.server/hudson/job/myprj/ws/trunk/myprj/nbproject/ // remote.repository = https://myprj.dev.java.net/svnroot/myprj // remote.module = https://myprj.dev.java.net/svnroot/myprj/trunk/myprj/nbproject // local.repository = https://myprj.dev.java.net/svnroot/myprj // local.module = https://myprj.dev.java.net/svnroot/myprj/trunk/myprj // checkoutPath = /svnroot/myprj/trunk/myprj/nbproject/build-impl.xml // infoURLPath = /svnroot/myprj/trunk/myprj/ // translatedPath = nbproject/build-impl.xml if (!remote.repository.getPath().equals(local.repository.getPath())) { LOG.log(Level.FINE, "repository mismatch between {0} and {1}", new Object[] {remote.repository, local.repository}); return null; } String remoteModule = new URL(remote.module + "/" + workspaceFile).getPath(); // NOI18N String localModuleBase = new URL(local.module + "/").getPath(); // NOI18N if (!remoteModule.startsWith(localModuleBase)) { LOG.log(Level.FINE, "checkout mismatch between {0} and {1}", new Object[] {localModuleBase, remoteModule}); return null; } String translatedPath = remoteModule.substring(localModuleBase.length()); LOG.log(Level.FINE, "translated path as {0}", translatedPath); return translatedPath; } catch (Exception x) { LOG.log(Level.FINE, "cannot translate path", x); return null; } } public @Override List parseChangeSet(final HudsonJobBuild build) { final Element changeSet; try { changeSet = XMLUtil.findElement(new ConnectionBuilder().job(build.getJob()).url(build.getUrl() + "api/xml?tree=changeSet[kind,items[user,msg,paths[file,editType],revision],revisions[module]]").parseXML().getDocumentElement(), "changeSet", null); } catch (IOException x) { LOG.log(Level.WARNING, "could not parse changelog for {0}: {1}", new Object[] {build, x}); return Collections.emptyList(); } if (!"svn".equals(Utilities.xpath("kind", changeSet))) { // NOI18N return null; } class SubversionItem implements HudsonJobChangeItem { final Element itemXML; SubversionItem(Element xml) { this.itemXML = xml; } public @Override String getUser() { return Utilities.xpath("user", itemXML); // NOI18N } public @Override String getMessage() { return Utilities.xpath("msg", itemXML); // NOI18N } public @Override Collection getFiles() { class SubversionFile implements HudsonJobChangeFile { final Element fileXML; SubversionFile(Element xml) { this.fileXML = xml; } public @Override String getName() { return Utilities.xpath("file", fileXML); // NOI18N } public @Override EditType getEditType() { return EditType.valueOf(Utilities.xpath("editType", fileXML)); // NOI18N } public @Override OutputListener hyperlink() { String module = Utilities.xpath("revision/module", changeSet); // NOI18N String rev = Utilities.xpath("revision", itemXML); // NOI18N if (module == null || !module.startsWith("http") || rev == null) { // NOI18N return null; } int r = Integer.parseInt(rev); String path = getName(); int startRev, endRev; switch (getEditType()) { case edit: startRev = r - 1; endRev = r; break; case add: startRev = 0; endRev = r; break; case delete: startRev = r - 1; endRev = 0; break; default: throw new AssertionError(); } return new SubversionHyperlink(module, path, startRev, endRev, build.getJob()); } } List files = new ArrayList(); NodeList nl = itemXML.getElementsByTagName("path"); // NOI18N for (int i = 0; i < nl.getLength(); i++) { files.add(new SubversionFile((Element) nl.item(i))); } return files; } } List items = new ArrayList(); NodeList nl = changeSet.getElementsByTagName("item"); // NOI18N for (int i = 0; i < nl.getLength(); i++) { items.add(new SubversionItem((Element) nl.item(i))); } return items; } } ----- Classpath: --------------------------------------------- bootPath: /space/jdk6/jre/lib/resources.jar:/space/jdk6/jre/lib/rt.jar:/space/jdk6/jre/lib/sunrsasign.jar:/space/jdk6/jre/lib/jsse.jar:/space/jdk6/jre/lib/jce.jar:/space/jdk6/jre/lib/charsets.jar:/space/jdk6/jre/lib/modules/jdk.boot.jar:/space/jdk6/jre/classes:/space/jdk6/jre/lib/ext/sunjce_provider.jar:/space/jdk6/jre/lib/ext/localedata.jar:/space/jdk6/jre/lib/ext/sunpkcs11.jar:/space/jdk6/jre/lib/ext/dnsns.jar classPath: /space/src/nb/main/nbbuild/netbeans/ide/modules/org-netbeans-modules-diff.jar:/space/src/nb/main/nbbuild/netbeans/ide/modules/org-netbeans-modules-hudson.jar:/space/src/nb/main/nbbuild/netbeans/platform/core/org-openide-filesystems.jar:/space/src/nb/main/nbbuild/netbeans/platform/modules/org-openide-io.jar:/space/src/nb/main/nbbuild/netbeans/platform/lib/org-openide-util.jar:/space/src/nb/main/nbbuild/netbeans/platform/lib/org-openide-util-lookup.jar:/space/src/nb/main/nbbuild/netbeans/platform/modules/org-openide-windows.jar sourcePath: /space/src/nb/main/hudson.subversion/src:/space/src/nb/main/hudson.subversion/build/classes-generated ----- Original exception --------------------------------------------- java.lang.AssertionError: Attr.visitNewClass tree [new Configuration(){ () { super(); } }] with constructor type [null] has symbol [symbol not found error] of kind [ 71] at com.sun.tools.javac.util.Assert.error(Assert.java:133) at com.sun.tools.javac.comp.Attr.visitNewClass(Attr.java:1873) at com.sun.tools.javac.tree.JCTree$JCNewClass.accept(JCTree.java:1377) at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:451) at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:424) at com.sun.tools.javac.comp.Attr.attribExpr(Attr.java:470) at com.sun.tools.javac.comp.Attr.visitReturn(Attr.java:1428) at com.sun.tools.javac.tree.JCTree$JCReturn.accept(JCTree.java:1245) at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:451) at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:424) at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:501) at com.sun.tools.javac.comp.Attr.attribStats(Attr.java:517) at com.sun.tools.javac.comp.Attr.visitBlock(Attr.java:948) at org.netbeans.modules.java.source.javac.NBAttr.visitBlock(NBAttr.java:82) at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:786) at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:451) at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:424) at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:501) at com.sun.tools.javac.comp.Attr.visitTry(Attr.java:1171) at com.sun.tools.javac.tree.JCTree$JCTry.accept(JCTree.java:1049) at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:451) at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:424) at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:501) at com.sun.tools.javac.comp.Attr.attribStats(Attr.java:517) at com.sun.tools.javac.comp.Attr.visitBlock(Attr.java:948) at org.netbeans.modules.java.source.javac.NBAttr.visitBlock(NBAttr.java:82) at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:786) at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:451) at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:424) at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:501) at com.sun.tools.javac.comp.Attr.visitMethodDef(Attr.java:861) at org.netbeans.modules.java.source.javac.NBAttr.visitMethodDef(NBAttr.java:76) at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:674) at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:451) at com.sun.tools.javac.comp.Attr.attribTree(Attr.java:424) at com.sun.tools.javac.comp.Attr.attribStat(Attr.java:501) at com.sun.tools.javac.comp.Attr.attribClassBody(Attr.java:3334) at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:3246) at com.sun.tools.javac.comp.Attr.attribClass(Attr.java:3177) at com.sun.tools.javac.comp.Attr.attrib(Attr.java:3151) at com.sun.tools.javac.main.JavaCompiler.attribute(JavaCompiler.java:1220) at com.sun.tools.javac.main.JavaCompiler.attribute(JavaCompiler.java:1195) at com.sun.tools.javac.api.JavacTaskImpl.analyze(JavacTaskImpl.java:466) at com.sun.tools.javac.api.JavacTaskImpl.analyze(JavacTaskImpl.java:445) at org.netbeans.modules.java.source.parsing.JavacParser.moveToPhase(JavacParser.java:592) at org.netbeans.modules.java.source.parsing.CompilationInfoImpl.toPhase(CompilationInfoImpl.java:385) at org.netbeans.api.java.source.CompilationController.toPhase(CompilationController.java:109) at org.netbeans.api.java.source.WorkingCopy.toPhase(WorkingCopy.java:179) at org.netbeans.modules.editor.java.JavaCompletionItem$DefaultConstructorItem$2.run(JavaCompletionItem.java:2466) at org.netbeans.api.java.source.ModificationResult$1.run(ModificationResult.java:137) at org.netbeans.modules.parsing.impl.TaskProcessor.callUserTask(TaskProcessor.java:583) at org.netbeans.modules.parsing.api.ParserManager$UserTaskAction.run(ParserManager.java:150) at org.netbeans.modules.parsing.api.ParserManager$UserTaskAction.run(ParserManager.java:134) at org.netbeans.modules.parsing.impl.TaskProcessor$2.call(TaskProcessor.java:200) at org.netbeans.modules.parsing.impl.TaskProcessor$2.call(TaskProcessor.java:197) at org.netbeans.modules.masterfs.filebasedfs.utils.FileChangedManager.priorityIO(FileChangedManager.java:168) at org.netbeans.modules.masterfs.providers.ProvidedExtensions.priorityIO(ProvidedExtensions.java:360) at org.netbeans.modules.parsing.impl.Utilities.runPriorityIO(Utilities.java:72) at org.netbeans.modules.parsing.impl.TaskProcessor.runUserTask(TaskProcessor.java:197) at org.netbeans.modules.parsing.api.ParserManager.parse(ParserManager.java:102) at org.netbeans.api.java.source.ModificationResult.runModificationTask(ModificationResult.java:125) at org.netbeans.modules.editor.java.JavaCompletionItem$DefaultConstructorItem.substituteText(JavaCompletionItem.java:2462) at org.netbeans.modules.editor.java.JavaCompletionItem.defaultAction(JavaCompletionItem.java:269) at org.netbeans.modules.editor.completion.CompletionImpl.dispatchKeyEvent(CompletionImpl.java:652) at org.netbeans.modules.editor.completion.CompletionImpl.keyPressed(CompletionImpl.java:381) at java.awt.AWTEventMulticaster.keyPressed(AWTEventMulticaster.java:250) at java.awt.Component.processKeyEvent(Component.java:6463) at javax.swing.JComponent.processKeyEvent(JComponent.java:2829) at java.awt.Component.processEvent(Component.java:6282) at java.awt.Container.processEvent(Container.java:2229) at java.awt.Component.dispatchEventImpl(Component.java:4861) at java.awt.Container.dispatchEventImpl(Container.java:2287) at java.awt.Component.dispatchEvent(Component.java:4687) at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1890) at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:752) at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1017) at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:889) at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:717) at java.awt.Component.dispatchEventImpl(Component.java:4731) at java.awt.Container.dispatchEventImpl(Container.java:2287) at java.awt.Window.dispatchEventImpl(Window.java:2713) at java.awt.Component.dispatchEvent(Component.java:4687) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707) at java.awt.EventQueue.access$000(EventQueue.java:101) at java.awt.EventQueue$3.run(EventQueue.java:666) at java.awt.EventQueue$3.run(EventQueue.java:664) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87) at java.awt.EventQueue$4.run(EventQueue.java:680) at java.awt.EventQueue$4.run(EventQueue.java:678) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) at java.awt.EventQueue.dispatchEvent(EventQueue.java:677) at org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:158) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105) at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)