@Override
 public void onDeleted(TopLevelItem item) throws IOException {
   for (ItemListener l : ItemListener.all()) {
     l.onDeleted(item);
   }
   getItems().remove(item);
 }
Example #2
0
  public synchronized TopLevelItem createProject(
      TopLevelItemDescriptor type, String name, boolean notify) throws IOException {
    acl.checkPermission(Job.CREATE);

    Jenkins.getInstance().getProjectNamingStrategy().checkName(name);
    if (parent.getItem(name) != null)
      throw new IllegalArgumentException("Project of the name " + name + " already exists");

    TopLevelItem item;
    try {
      item = type.newInstance(parent, name);
    } catch (Exception e) {
      throw new IllegalArgumentException(e);
    }
    try {
      callOnCreatedFromScratch(item);
    } catch (AbstractMethodError e) {
      // ignore this error. Must be older plugin that doesn't have this method
    }
    item.save();
    add(item);
    Jenkins.getInstance().rebuildDependencyGraph();

    if (notify) ItemListener.fireOnCreated(item);

    return item;
  }
Example #3
0
  public synchronized TopLevelItem createProjectFromXML(String name, InputStream xml)
      throws IOException {
    acl.checkPermission(Job.CREATE);

    Jenkins.getInstance().getProjectNamingStrategy().checkName(name);
    // place it as config.xml
    File configXml = Items.getConfigFile(getRootDirFor(name)).getFile();
    configXml.getParentFile().mkdirs();
    try {
      IOUtils.copy(xml, configXml);

      // load it
      TopLevelItem result;
      Items.updatingByXml.set(true);
      try {
        result = (TopLevelItem) Items.load(parent, configXml.getParentFile());
      } finally {
        Items.updatingByXml.set(false);
      }
      add(result);

      ItemListener.fireOnCreated(result);
      Jenkins.getInstance().rebuildDependencyGraph();

      return result;
    } catch (IOException e) {
      // if anything fails, delete the config file to avoid further confusion
      Util.deleteRecursive(configXml.getParentFile());
      throw e;
    }
  }
Example #4
0
  /** Accepts submission from the configuration page. */
  @RequirePOST
  public synchronized void doConfigSubmit(StaplerRequest req, StaplerResponse rsp)
      throws IOException, ServletException, FormException {
    checkPermission(CONFIGURE);

    description = req.getParameter("description");

    keepDependencies = req.getParameter("keepDependencies") != null;

    try {
      JSONObject json = req.getSubmittedForm();

      setDisplayName(json.optString("displayNameOrNull"));

      if (req.getParameter("logrotate") != null)
        logRotator = LogRotator.DESCRIPTOR.newInstance(req, json.getJSONObject("logrotate"));
      else logRotator = null;

      DescribableList<JobProperty<?>, JobPropertyDescriptor> t =
          new DescribableList<JobProperty<?>, JobPropertyDescriptor>(NOOP, getAllProperties());
      t.rebuild(
          req,
          json.optJSONObject("properties"),
          JobPropertyDescriptor.getPropertyDescriptors(Job.this.getClass()));
      properties.clear();
      for (JobProperty p : t) {
        p.setOwner(this);
        properties.add(p);
      }

      submit(req, rsp);

      save();
      ItemListener.fireOnUpdated(this);

      String newName = req.getParameter("name");
      final ProjectNamingStrategy namingStrategy = Jenkins.getInstance().getProjectNamingStrategy();
      if (newName != null && !newName.equals(name)) {
        // check this error early to avoid HTTP response splitting.
        Jenkins.checkGoodName(newName);
        namingStrategy.checkName(newName);
        rsp.sendRedirect("rename?newName=" + URLEncoder.encode(newName, "UTF-8"));
      } else {
        if (namingStrategy.isForceExistingJobs()) {
          namingStrategy.checkName(name);
        }
        FormApply.success(".").generateResponse(req, rsp, null);
      }
    } catch (JSONException e) {
      StringWriter sw = new StringWriter();
      PrintWriter pw = new PrintWriter(sw);
      pw.println("Failed to parse form data. Please report this problem as a bug");
      pw.println("JSON=" + req.getSubmittedForm());
      pw.println();
      e.printStackTrace(pw);

      rsp.setStatus(SC_BAD_REQUEST);
      sendError(sw.toString(), req, rsp, true);
    }
  }
Example #5
0
  /**
   * Copies an existing {@link TopLevelItem} to a new name.
   *
   * <p>The caller is responsible for calling {@link ItemListener#fireOnCopied(Item, Item)}. This
   * method cannot do that because it doesn't know how to make the newly added item reachable from
   * the parent.
   */
  @SuppressWarnings({"unchecked"})
  public synchronized <T extends TopLevelItem> T copy(T src, String name) throws IOException {
    acl.checkPermission(Job.CREATE);

    T result = (T) createProject(src.getDescriptor(), name, false);

    // copy config
    Util.copyFile(Items.getConfigFile(src).getFile(), Items.getConfigFile(result).getFile());

    // reload from the new config
    Items.updatingByXml.set(true);
    try {
      result = (T) Items.load(parent, result.getRootDir());
    } finally {
      Items.updatingByXml.set(false);
    }
    result.onCopiedFrom(src);

    add(result);
    ItemListener.fireOnCopied(src, result);
    Hudson.getInstance().rebuildDependencyGraph();

    return result;
  }
Example #6
0
    /**
     * Renames this item.
     * Not all the Items need to support this operation, but if you decide to do so,
     * you can use this method.
     */
    protected void renameTo(String newName) throws IOException {
        // always synchronize from bigger objects first
        final ItemGroup parent = getParent();
        synchronized (parent) {
            synchronized (this) {
                // sanity check
                if (newName == null)
                    throw new IllegalArgumentException("New name is not given");

                // noop?
                if (this.name.equals(newName))
                    return;

                Item existing = parent.getItem(newName);
                if (existing != null && existing!=this)
                    // the look up is case insensitive, so we need "existing!=this"
                    // to allow people to rename "Foo" to "foo", for example.
                    // see http://www.nabble.com/error-on-renaming-project-tt18061629.html
                    throw new IllegalArgumentException("Job " + newName
                            + " already exists");

                String oldName = this.name;
                File oldRoot = this.getRootDir();

                doSetName(newName);
                File newRoot = this.getRootDir();

                boolean success = false;

                try {// rename data files
                    boolean interrupted = false;
                    boolean renamed = false;

                    // try to rename the job directory.
                    // this may fail on Windows due to some other processes
                    // accessing a file.
                    // so retry few times before we fall back to copy.
                    for (int retry = 0; retry < 5; retry++) {
                        if (oldRoot.renameTo(newRoot)) {
                            renamed = true;
                            break; // succeeded
                        }
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            // process the interruption later
                            interrupted = true;
                        }
                    }

                    if (interrupted)
                        Thread.currentThread().interrupt();

                    if (!renamed) {
                        // failed to rename. it must be that some lengthy
                        // process is going on
                        // to prevent a rename operation. So do a copy. Ideally
                        // we'd like to
                        // later delete the old copy, but we can't reliably do
                        // so, as before the VM
                        // shuts down there might be a new job created under the
                        // old name.
                        Copy cp = new Copy();
                        cp.setProject(new org.apache.tools.ant.Project());
                        cp.setTodir(newRoot);
                        FileSet src = new FileSet();
                        src.setDir(oldRoot);
                        cp.addFileset(src);
                        cp.setOverwrite(true);
                        cp.setPreserveLastModified(true);
                        cp.setFailOnError(false); // keep going even if
                                                    // there's an error
                        cp.execute();

                        // try to delete as much as possible
                        try {
                            Util.deleteRecursive(oldRoot);
                        } catch (IOException e) {
                            // but ignore the error, since we expect that
                            e.printStackTrace();
                        }
                    }

                    success = true;
                } finally {
                    // if failed, back out the rename.
                    if (!success)
                        doSetName(oldName);
                }

                callOnRenamed(newName, parent, oldName);

                for (ItemListener l : ItemListener.all())
                    l.onRenamed(this, oldName, newName);
            }
        }
    }
Example #7
0
 /**
  * Sets the project description HTML.
  */
 public void setDescription(String description) throws IOException {
     this.description = description;
     save();
     ItemListener.fireOnUpdated(this);
 }