private boolean updateExistingItem(AbstractItem item, String config) { boolean created; // Leverage XMLUnit to perform diffs Diff diff; try { String oldJob = item.getConfigFile().asString(); diff = XMLUnit.compareXML(oldJob, config); if (diff.similar()) { LOGGER.log(Level.FINE, format("Item %s is identical", item.getName())); return false; } } catch (Exception e) { // It's not a big deal if we can't diff, we'll just move on LOGGER.warning(e.getMessage()); } LOGGER.log(Level.FINE, format("Updating item %s as %s", item.getName(), config)); Source streamSource = new StreamSource(new StringReader(config)); try { item.updateByXml(streamSource); created = true; } catch (IOException e) { LOGGER.log(Level.WARNING, format("Error writing updated item to file."), e); created = false; } return created; }
@Override /** * Called after the user has changed the project name of a job and then clicked on submit. * * @param item The item that has been renamed. The new project name is already in item.getName() * @param oldName the old name * @param newName the new name */ public void onRenamed(Item item, String oldName, String newName) { // bug 5077308 - Display name field should be cleared when you rename a job. if (item instanceof AbstractItem) { AbstractItem abstractItem = (AbstractItem) item; if (oldName.equals(abstractItem.getDisplayName())) { // the user renamed the job, but the old project name which is shown as the // displayname if no displayname was set, has been set into the displayname field. // This means that the displayname was never set, so we want to set it // to null as it was before try { LOGGER.info( String.format( "onRenamed():Setting displayname to null for item.name=%s", item.getName())); abstractItem.setDisplayName(null); } catch (IOException ioe) { LOGGER.log( Level.WARNING, String.format( "onRenamed():Exception while trying to clear the displayName for Item.name:%s", item.getName()), ioe); } } } }
private String lookupJob(String path) throws IOException { LOGGER.log(Level.FINE, format("Looking up item %s", path)); AbstractItem item = lookupStrategy.getItem(build.getProject(), path, AbstractItem.class); if (item != null) { XmlFile xmlFile = item.getConfigFile(); String jobXml = xmlFile.asString(); LOGGER.log(Level.FINE, format("Looked up item with config %s", jobXml)); return jobXml; } else { LOGGER.log(Level.WARNING, format("No item called %s could be found.", path)); throw new IOException(format("No item called %s could be found.", path)); } }
@Override public void onCopiedFrom(Item src) { super.onCopiedFrom(src); synchronized (this) { this.nextBuildNumber = 1; // reset the next build number this.holdOffBuildUntilSave = true; } }
@Override /** * Called after the user has clicked OK in the New Job page when Copy existing job has been * selected. The fields in item will be displayed in when the config page is loaded displayed. */ public void onCopied(Item src, Item item) { // bug 5056825 - Display name field should be cleared when you copy a job. if (item instanceof AbstractItem) { AbstractItem dest = (AbstractItem) item; try { dest.setDisplayName(null); } catch (IOException ioe) { LOGGER.log( Level.WARNING, String.format( "onCopied():Exception while trying to clear the displayName for Item.name:%s", item.getName()), ioe); } } }
@Override protected void performDelete() throws IOException, InterruptedException { // if a build is in progress. Cancel it. RunT lb = getLastBuild(); if (lb != null) { Executor e = lb.getExecutor(); if (e != null) { e.interrupt(); // should we block until the build is cancelled? } } super.performDelete(); }
@Override public void onLoad(ItemGroup<? extends Item> parent, String name) throws IOException { super.onLoad(parent, name); TextFile f = getNextBuildNumberFile(); if (f.exists()) { // starting 1.28, we store nextBuildNumber in a separate file. // but old Hudson didn't do it, so if the file doesn't exist, // assume that nextBuildNumber was read from config.xml try { synchronized (this) { this.nextBuildNumber = Integer.parseInt(f.readTrim()); } } catch (NumberFormatException e) { // try to infer the value of the next build number from the existing build records. See // JENKINS-11563 File[] folders = this.getBuildDir() .listFiles( new FileFilter() { public boolean accept(File file) { return file.isDirectory() && file.getName().matches("[0-9]+"); } }); if (folders == null || folders.length == 0) { this.nextBuildNumber = 1; } else { Collection<Integer> foldersInt = Collections2.transform( Arrays.asList(folders), new Function<File, Integer>() { public Integer apply(File file) { return Integer.parseInt(file.getName()); } }); this.nextBuildNumber = Collections.max(foldersInt) + 1; } saveNextBuildNumber(); } } else { // From the old Hudson, or doCreateItem. Create this file now. saveNextBuildNumber(); save(); // and delete it from the config.xml } if (properties == null) // didn't exist < 1.72 properties = new CopyOnWriteList<JobProperty<? super JobT>>(); for (JobProperty p : properties) p.setOwner(this); }
@Override public void cook(Recipe recipe, ImportReportList reportList) throws IOException { // expansion of this is deferred XStreamDOM actual = recipe.createImportOptions().apply(definition); ByteArrayOutputStream baos = new ByteArrayOutputStream(); XStreamDOM.ConverterImpl c = new ConverterImpl(); c.marshal(actual, new XppDriver().createWriter(baos), null); ModifiableTopLevelItemGroup g = Jenkins.getInstance(); TopLevelItem j = g.getItem(name); InputStream is = new ByteArrayInputStream(baos.toByteArray()); if (j == null) { j = g.createProjectFromXML(name, is); } else if (j instanceof AbstractItem) { Source source = new StreamSource(is); ((AbstractItem) j).updateByXml(source); } else { throw new IOException("Cannot update " + j + " in place"); } reportList.add(new ImportReportImpl(j)); }
private File getProjectArchiveDir(AbstractItem project) { return new File(project.getRootDir(), "cucumber-html-reports"); }
/*package*/ static File getCoberturaReportDir(AbstractItem project) { return new File(project.getRootDir(), "cobertura"); }
/** Renames a job. */ @Override public void renameTo(String newName) throws IOException { super.renameTo(newName); }
@Override public synchronized void save() throws IOException { super.save(); holdOffBuildUntilSave = false; }