private boolean uriMatchesComparison(URI actual, ComparisonTerm comparison) {
   String actualString = actual.toString();
   Value value = comparison.operand();
   if (!(value instanceof UriRefValue)) {
     throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST);
   }
   UriRefValue uriRef = (UriRefValue) value;
   String uri = uriRef.value();
   switch (comparison.operator()) {
     case EQUALS:
       return actualString.equals(uri);
     case NOT_EQUALS:
       return !actualString.equals(uri);
     default:
       throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST);
   }
 }
  /*
   * Determine the Hudson parameter values from the OSLC parameter instances
   * in the AutomationRequest
   */
  private List<ParameterValue> getParameterValues(
      AbstractProject<?, ?> project, ParameterInstance[] parameters) {
    ParametersDefinitionProperty pp = project.getProperty(ParametersDefinitionProperty.class);
    if (pp == null) {
      LOG.log(Level.FINE, "Job does not take parameters: " + project.getName());
      throw HttpResponses.status(
          HttpServletResponse.SC_BAD_REQUEST); // This build is not parameterized.
    }

    HashMap<String, String> inputMap = new HashMap<String, String>();
    for (ParameterInstance param : parameters) {
      inputMap.put(param.getName(), param.getValue());
    }

    List<ParameterValue> values = new ArrayList<ParameterValue>();
    for (ParameterDefinition def : pp.getParameterDefinitions()) {
      String inputValue = inputMap.get(def.getName());
      if (inputValue == null) {
        ParameterValue defaultValue = def.getDefaultParameterValue();
        if (defaultValue == null) {
          LOG.log(
              Level.FINE, "Missing parameter " + def.getName() + " for job " + project.getName());
          throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST);
        }

        values.add(defaultValue);
      } else {
        if (def instanceof SimpleParameterDefinition) {
          SimpleParameterDefinition simple = (SimpleParameterDefinition) def;
          values.add(simple.createValue(inputValue));
        } else {
          LOG.log(
              Level.WARNING,
              "Unsupported parameter type with name "
                  + def.getName()
                  + " for project "
                  + project.getName());
          throw HttpResponses.status(HttpServletResponse.SC_NOT_IMPLEMENTED);
        }
      }
    }

    return values;
  }
  /*
   * Parse the where clause from the oslc.where and oslc.prefix parameters.
   */
  private WhereClause parseWhere(String where, String prefixes) {
    final Map<String, String> prefixMap;
    if (prefixes == null) {
      prefixMap = PREFIX_MAP;
    } else {
      try {
        prefixMap = QueryUtils.parsePrefixes(prefixes);
      } catch (ParseException e) {
        LOG.log(Level.FINE, "Bad oslc.prefix", e);
        throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST);
      }
    }

    try {
      return QueryUtils.parseWhere(where, prefixMap);
    } catch (ParseException e) {
      LOG.log(Level.FINE, "Bad oslc.where", e);
      throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST);
    }
  }
 private boolean uriMatches(URI actual, SimpleTerm term) {
   switch (term.type()) {
     case COMPARISON:
       return uriMatchesComparison(actual, (ComparisonTerm) term);
     case IN_TERM:
       return uriMatchesInTerm(actual, (InTerm) term);
     case NESTED:
       throw HttpResponses.status(HttpServletResponse.SC_NOT_IMPLEMENTED);
     default:
       return true;
   }
 }
  private boolean uriMatchesInTerm(URI actual, InTerm in) {
    String actualString = actual.toString();

    for (Object element : in.values()) {
      Value value = (Value) element;
      if (!(value instanceof UriRefValue)) {
        throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST);
      }

      UriRefValue uriRef = (UriRefValue) value;
      String uri = uriRef.value();
      if (uri.equals(actualString)) {
        return true;
      }
    }

    return false;
  }
  /*
   * Set the correct media based on the request Accept header and marshal the
   * response. Set any common headers for all responses.
   */
  private void marshal(Object objects[]) throws IOException {
    OSLC4JMarshaller marshaller = OSLC4JContext.newInstance().createMarshaller();

    MediaType type = AcceptUtil.matchMediaType(Stapler.getCurrentRequest());
    if (type == null) {
      throw HttpResponses.status(HttpServletResponse.SC_NOT_ACCEPTABLE);
    }

    marshaller.setMediaType(type);

    StaplerResponse response = Stapler.getCurrentResponse();
    response.setCharacterEncoding("UTF-8");
    response.setHeader("OSLC-Core-Version", "2.0");
    response.setHeader("Content-Type", type.toString());
    response.setHeader("Vary", "Accept, Accept-Encoding");

    // Use WriterOutputStream since Stapler has already called response.getWriter().
    WriterOutputStream out = new WriterOutputStream(response.getWriter());
    marshaller.marshal(objects, out);
  }
 private void requireMethod(String method) {
   if (!method.equals(Stapler.getCurrentRequest().getMethod())) {
     throw HttpResponses.status(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
   }
 }
  /*
   * Path: /auto/scheduleBuild
   *
   * POST to create automation requests to schedule builds.
   */
  public void doScheduleBuild(StaplerRequest request, StaplerResponse response) throws Exception {
    requirePOST();

    OSLC4JUnmarshaller unmarshaller = OSLC4JContext.newInstance().createUnmarshaller();

    String contentType = request.getContentType();
    if (contentType == null) {
      throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST);
    }
    unmarshaller.setMediaType(MediaType.valueOf(contentType));

    final AutomationRequest autoRequest =
        unmarshaller.unmarshal(request.getInputStream(), AutomationRequest.class);
    if (autoRequest == null) {
      throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST);
    }

    Link planLink = autoRequest.getExecutesAutomationPlan();
    if (planLink == null) {
      throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST);
    }

    URI planURI = planLink.getValue();
    String jobName = getJobNameFromURI(planURI);
    if (jobName == null) {
      throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST);
    }

    Job<?, ?> job = getJob(jobName);
    if (job == null) {
      throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST);
    }

    if (!job.isBuildable()) {
      throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST);
    }

    if (!(job instanceof AbstractProject)) {
      LOG.log(
          Level.WARNING,
          "Cannot schedule builds for jobs that don't extend AbstractProject: " + jobName);
      throw HttpResponses.status(HttpServletResponse.SC_BAD_REQUEST);
    }

    AbstractProject<?, ?> project = (AbstractProject<?, ?>) job;
    int nextBuildNumber = project.getNextBuildNumber();
    Cause cause =
        new Cause() {
          @Override
          public String getShortDescription() {
            String description = autoRequest.getDescription();
            return description != null ? description : "OSLC Automation Request";
          }
        };

    ParameterInstance[] parameters = autoRequest.getInputParameters();
    boolean suceeded;
    if (parameters.length == 0) {
      suceeded = project.scheduleBuild(cause);
    } else {
      List<ParameterValue> values = getParameterValues(project, parameters);
      suceeded =
          project.scheduleBuild2(project.getQuietPeriod(), cause, new ParametersAction(values))
              != null;
    }

    if (!suceeded) {
      // Build already queued.
      LOG.log(
          Level.WARNING,
          "Automation request rejected (409 conflict) since build is already queued: " + jobName);
      throw HttpResponses.status(HttpServletResponse.SC_CONFLICT);
    }

    URI requestURI = getAutoRequestURI(job, nextBuildNumber);
    response.setStatus(HttpServletResponse.SC_CREATED);
    response.setHeader("Location", requestURI.toString());
  }
  // TODO: Break up this method and clean up URL handling.
  public void doJob(StaplerRequest request, StaplerResponse response)
      throws IOException, URISyntaxException, ServletException {
    requireGET();

    MediaType type = AcceptUtil.matchMediaType(request, ACCEPTABLE);
    if (type == null) {
      throw HttpResponses.status(HttpServletResponse.SC_NOT_ACCEPTABLE);
    }

    String restOfPath = request.getRestOfPath();
    if (restOfPath == null) {
      throw HttpResponses.notFound();
    }

    // Remove leading '/'
    restOfPath = restOfPath.substring(1);
    String segments[] = restOfPath.split("/");

    // URI patterns:
    //   <job-name>
    //   <job-name>/preview
    //   <job-name>/run/<run-number>
    //   <job-name>/run/<run-number>/preview
    //   <job-name>/run/<run-number>/request

    // Find the job.
    String jobName = segments[0];
    Job<?, ?> job = getJob(jobName);
    if (job == null) {
      throw HttpResponses.notFound();
    }

    // Is it a run?
    //   <job-name>/run/<run-number>
    if (segments.length >= 3 && PATH_RUN.equals(segments[1])) {
      String runNumber = segments[2];
      int i;
      try {
        i = Integer.valueOf(Integer.parseInt(runNumber));
      } catch (NumberFormatException e) {
        throw HttpResponses.notFound();
      }

      Run<?, ?> run = job.getBuildByNumber(i);
      if (run == null) {
        throw HttpResponses.notFound();
      }

      if (segments.length == 4) {
        // Is it a run preview?
        //   <job-name>/run/<run-number>/preview
        if (PATH_PREVIEW.equals(segments[3])) {
          /*
           * See /hudson-oslc-auto/src/main/resources/hudson/model/Run/preview.jelly
           */
          response.forward(run, "preview", request);
          return;
        }

        // Is it an AutomationRequest?
        //   <job-name>/run/<run-number>/request
        if (PATH_REQUEST.equals(segments[3])) {
          AutomationRequest autoRequest = toAutomationRequest(request, job, run);
          marshal(autoRequest);
        }

        if ("buildStatus".equals(segments[3])) {
          throw HttpResponses.redirectViaContextPath(run.getUrl() + "/buildStatus");
        }
      } else if (segments.length == 3) { // <job-name>/run/<run-number>
        if (MediaType.TEXT_HTML_TYPE.isCompatible(type)) {
          throw HttpResponses.redirectViaContextPath(run.getUrl());
        }

        if (MarshallerConstants.MT_OSLC_COMPACT.isCompatible(type)) {
          handleCompact(job, run);
        } else {
          AutomationResult result = toAutomationResult(request, job, run);
          marshal(result);
        }
      } else {
        throw HttpResponses.notFound();
      }
    } else {
      // Is it a job preview?
      //   <job-name>/preview
      if (segments.length == 2 && PATH_PREVIEW.equals(segments[1])) {
        /*
         * See /hudson-oslc-auto/src/main/resources/hudson/model/Job/preview.jelly
         */
        response.forward(job, "preview", request);
        return;
      }

      if (segments.length != 1) {
        throw HttpResponses.notFound();
      }

      // Is it just a job name with no other segments?
      //   <job-name>
      if (MediaType.TEXT_HTML_TYPE.isCompatible(type)) {
        throw HttpResponses.redirectViaContextPath(job.getUrl());
      }

      if (MarshallerConstants.MT_OSLC_COMPACT.isCompatible(type)) {
        handleCompact(job);
      } else {
        AutomationPlan plan = toAutomationPlan(job);
        marshal(plan);
      }
    }
  }