/** Accept the representation of a mail received from a sender, and create it. */ @Override public void acceptRepresentation(Representation entity) throws ResourceException { final Form form = new Form(entity); final Mail mail = new Mail(); mail.setStatus(Mail.STATUS_RECEIVED); // Look for an existing contact or create it. final String senderAddress = form.getFirstValue("senderAddress"); final String senderName = form.getFirstValue("senderName"); Contact contact = getObjectsFacade().lookForContact(senderAddress, this.mailbox); if (contact == null) { contact = new Contact(); contact.setMailAddress(senderAddress); contact.setName(senderName); } mail.setSender(contact); mail.setMessage(form.getFirstValue("message")); mail.setSubject(form.getFirstValue("subject")); // form2.add("sendingDate", mail.getSendingDate().toString()); final Series<Parameter> recipients = form.subList("recipient"); for (final Parameter recipient : recipients) { contact = getObjectsFacade().lookForContact(recipient.getValue(), this.mailbox); if (contact == null) { contact = new Contact(); final String[] recipientValues = recipient.getValue().split("\\$"); contact.setMailAddress(recipientValues[0]); contact.setName(recipientValues[1]); } mail.getRecipients().add(contact); } getObjectsFacade().createMail(this.mailbox, mail); }
@Override public void formatResponse( ChallengeWriter cw, ChallengeResponse challenge, Request request, Series<Header> httpHeaders) { if (challenge.getIdentifier() != null) { cw.appendQuotedChallengeParameter("username", challenge.getIdentifier()); } if (challenge.getRealm() != null) { cw.appendQuotedChallengeParameter("realm", challenge.getRealm()); } if (challenge.getServerNonce() != null) { cw.appendQuotedChallengeParameter("nonce", challenge.getServerNonce()); } if (challenge.getDigestRef() != null) { challenge.setDigestRef(new Reference(request.getResourceRef().getPath())); cw.appendQuotedChallengeParameter("uri", challenge.getDigestRef().toString()); } char[] responseDigest = formatResponseDigest(challenge, request); if (responseDigest != null) { cw.appendQuotedChallengeParameter("response", new String(responseDigest)); } if ((challenge.getDigestAlgorithm() != null) && !Digest.ALGORITHM_MD5.equals(challenge.getDigestAlgorithm())) { cw.appendChallengeParameter("algorithm", challenge.getDigestAlgorithm()); } if (challenge.getClientNonce() != null) { cw.appendQuotedChallengeParameter("cnonce", challenge.getClientNonce()); } if (challenge.getOpaque() != null) { cw.appendQuotedChallengeParameter("opaque", challenge.getOpaque()); } if (challenge.getQuality() != null) { cw.appendChallengeParameter("qop", challenge.getQuality()); } if ((challenge.getQuality() != null) && (challenge.getServerNounceCount() > 0)) { cw.appendChallengeParameter("nc", challenge.getServerNounceCountAsHex()); } for (Parameter param : challenge.getParameters()) { if (HeaderUtils.isToken(param.getValue())) { cw.appendChallengeParameter(param); } else { cw.appendQuotedChallengeParameter(param); } } }
/** * Writes a header line. * * @param header The header to write. * @param os The output stream. * @throws IOException */ public static void writeHeader(Parameter header, OutputStream os) throws IOException { os.write(header.getName().getBytes()); os.write(':'); os.write(' '); os.write(header.getValue().getBytes()); os.write(13); // CR os.write(10); // LF }
/** * Read a header. Return null if the last header was already read. * * @param is The message input stream. * @param sb The string builder to reuse. * @return The header read or null. * @throws IOException */ public static Parameter readHeader(InputStream is, StringBuilder sb) throws IOException { Parameter result = null; // Detect the end of headers int next = is.read(); if (HttpUtils.isCarriageReturn(next)) { next = is.read(); if (!HttpUtils.isLineFeed(next)) { throw new IOException( "Invalid end of headers. Line feed missing after the carriage return."); } } else { result = new Parameter(); // Parse the header name while ((next != -1) && (next != ':')) { sb.append((char) next); next = is.read(); } if (next == -1) { throw new IOException("Unable to parse the header name. End of stream reached too early."); } else { result.setName(sb.toString()); sb.delete(0, sb.length()); next = is.read(); while (HttpUtils.isSpace(next)) { // Skip any separator space between colon and header value next = is.read(); } // Parse the header value while ((next != -1) && (!HttpUtils.isCarriageReturn(next))) { sb.append((char) next); next = is.read(); } if (next == -1) { throw new IOException( "Unable to parse the header value. End of stream reached too early."); } else { next = is.read(); if (HttpUtils.isLineFeed(next)) { result.setValue(sb.toString()); sb.delete(0, sb.length()); } else { throw new IOException( "Unable to parse the HTTP header value. The carriage return must be followed by a line feed."); } } } } return result; }
@Override public void doInit() { super.doInit(); final Form form = getRequest().getResourceRef().getQueryAsForm(); for (Parameter parameter : form) { params.put(parameter.getName(), parameter.getValue()); } }
/** * Returns the canonicalized resource name. * * @param resourceRef The resource reference. * @return The canonicalized resource name. */ private static String getCanonicalizedResourceName(Reference resourceRef) { Form form = resourceRef.getQueryAsForm(); Parameter param = form.getFirst("comp", true); if (param != null) { StringBuilder sb = new StringBuilder(resourceRef.getPath()); return sb.append("?").append("comp=").append(param.getValue()).toString(); } return resourceRef.getPath(); }
private static void completeOperationQueryParameter( Operation operation, MethodAnnotationInfo mai) { if (mai.getQuery() != null) { Form form = new Form(mai.getQuery()); for (org.restlet.data.Parameter parameter : form) { QueryParameter queryParameter = new QueryParameter(); queryParameter.setName(parameter.getName()); queryParameter.setRequired(true); queryParameter.setDescription( StringUtils.isNullOrEmpty(parameter.getValue()) ? "" : "Value: " + parameter.getValue()); queryParameter.setDefaultValue(parameter.getValue()); queryParameter.setAllowMultiple(false); operation.getQueryParameters().add(queryParameter); } } }
@Override public void formatRequest( ChallengeWriter cw, ChallengeRequest challenge, Response response, Series<Header> httpHeaders) throws IOException { // Format the parameters WWW-Authenticate: OAuth realm='Example // Service', error='expired-token' cw.append("realm='"); cw.append(challenge.getRealm()); cw.append("'"); for (Parameter p : challenge.getParameters()) { cw.append(", "); cw.append(p.getName()); cw.append("='"); cw.append(p.getValue()); cw.append("'"); } }
@Override public void handle(Request request, Response response) { Form form = request.getResourceRef().getQueryAsForm(); List<Range> ranges = request.getRanges(); boolean match = false; for (Parameter parameter : form) { long index = 0; long length = 0; String value = parameter.getValue(); if (value.startsWith("-")) { index = Range.INDEX_LAST; length = Long.parseLong(value.substring(1)); } else if (value.endsWith("-")) { index = Long.parseLong(value.substring(0, value.length() - 1)); length = Range.SIZE_MAX; } else { String[] tab = value.split("-"); if (tab.length == 2) { index = Long.parseLong(tab[0]); length = Long.parseLong(tab[1]) - index; } } boolean found = false; for (Range range : ranges) { found = (index == range.getIndex()) && (length == range.getSize()); if (found) { break; } } if (!found) { break; } match = true; } if (match) { response.setStatus(Status.SUCCESS_OK); response.setEntity(str1000, MediaType.TEXT_PLAIN); } else { response.setStatus(Status.CLIENT_ERROR_BAD_REQUEST); } }
/** * Extract the quality value. If the value is not found, 1 is returned. * * @param parameters The preference parameters. * @return The quality value. */ protected float extractQuality(Series<Parameter> parameters) { float result = 1F; boolean found = false; if (parameters != null) { Parameter param = null; for (final Iterator<Parameter> iter = parameters.iterator(); !found && iter.hasNext(); ) { param = iter.next(); if (param.getName().equals("q")) { result = PreferenceUtils.parseQuality(param.getValue()); found = true; // Remove the quality parameter as we will directly store it // in the Preference object iter.remove(); } } } return result; }
@Override public PreferenceWriter append(Preference<?> pref) { append(pref.getMetadata().getName()); if (pref.getQuality() < 1F) { append(";q="); appendQuality(pref.getQuality()); } if (pref.getParameters() != null) { Parameter param; for (Iterator<Parameter> iter = pref.getParameters().iterator(); iter.hasNext(); ) { param = iter.next(); if (param.getName() != null) { append(';').append(param.getName()); if ((param.getValue() != null) && (param.getValue().length() > 0)) { append('=').append(param.getValue()); } } } } return this; }
/** * Extract the media parameters. Only leave as the quality parameter if found. Modifies the * parameters list. * * @param parameters All the preference parameters. * @return The media parameters. */ protected Series<Parameter> extractMediaParams(Series<Parameter> parameters) { Series<Parameter> result = null; boolean qualityFound = false; Parameter param = null; if (parameters != null) { result = new Form(); for (final Iterator<Parameter> iter = parameters.iterator(); !qualityFound && iter.hasNext(); ) { param = iter.next(); if (param.getName().equals("q")) { qualityFound = true; } else { iter.remove(); result.add(param); } } } return result; }
/** * Sends the request to the client. Commits the request line, headers and optional entity and send * them over the network. * * @param request The high-level request. * @return The result status. */ @Override public Status sendRequest(Request request) { Status result = null; try { final Representation entity = request.getEntity(); // Set the request headers for (final Parameter header : getRequestHeaders()) { getHttpMethod().addRequestHeader(header.getName(), header.getValue()); } // For those method that accept enclosing entites, provide it if ((entity != null) && (getHttpMethod() instanceof EntityEnclosingMethod)) { final EntityEnclosingMethod eem = (EntityEnclosingMethod) getHttpMethod(); eem.setRequestEntity( new RequestEntity() { public long getContentLength() { return entity.getSize(); } public String getContentType() { return (entity.getMediaType() != null) ? entity.getMediaType().toString() : null; } public boolean isRepeatable() { return !entity.isTransient(); } public void writeRequest(OutputStream os) throws IOException { entity.write(os); } }); } // Ensure that the connection is active this.clientHelper.getHttpClient().executeMethod(getHttpMethod()); // Now we can access the status code, this MUST happen after closing // any open request stream. result = new Status(getStatusCode(), null, getReasonPhrase(), null); // If there is no response body, immediately release the connection if (getHttpMethod().getResponseBodyAsStream() == null) { getHttpMethod().releaseConnection(); } } catch (IOException ioe) { this.clientHelper .getLogger() .log( Level.WARNING, "An error occurred during the communication with the remote HTTP server.", ioe); result = new Status(Status.CONNECTOR_ERROR_COMMUNICATION, ioe); // Release the connection getHttpMethod().releaseConnection(); } return result; }
@Get public void resetMethod(String body) { String urilistener = null; String timeoutString = null; Long timeout = -1l; short warmStartValue = 0x00; Parameter urilistenerParam = getRequest().getResourceRef().getQueryAsForm().getFirst(Resources.URI_PARAM_URILISTENER); if (urilistenerParam != null) { urilistener = urilistenerParam.getValue().trim(); } Parameter timeoutParam = getRequest().getResourceRef().getQueryAsForm().getFirst(Resources.URI_PARAM_TIMEOUT); if (timeoutParam != null) { timeoutString = timeoutParam.getValue().trim(); try { timeout = Long.decode("0x" + timeoutString); } catch (NumberFormatException nfe) { Info info = new Info(); Status _st = new Status(); _st.setCode((short) GatewayConstants.GENERAL_ERROR); _st.setMessage(nfe.getMessage()); info.setStatus(_st); Info.Detail detail = new Info.Detail(); info.setDetail(detail); getResponse().setEntity(Util.marshal(info), MediaType.APPLICATION_XML); return; } if (!Util.isUnsigned32(timeout)) { Info info = new Info(); Status _st = new Status(); _st.setCode((short) GatewayConstants.GENERAL_ERROR); _st.setMessage("Wrong timeout"); info.setStatus(_st); Info.Detail detail = new Info.Detail(); info.setDetail(detail); getResponse().setEntity(Util.marshal(info), MediaType.APPLICATION_XML); return; } } else { // The timeout parameter is optional. If not provided we use a // default. timeout = (long) INTERNAL_TIMEOUT; } // TODO Set the right warm start value. String warmparamString = null; Parameter warmparam = getRequest() .getResourceRef() .getQueryAsForm() .getFirst(Resources.URI_PARAM_START_MODE_RESET); if (warmparam != null) { warmparamString = warmparam.getValue().trim(); try { warmStartValue = Short.decode(warmparamString); } catch (NumberFormatException nfe) { Info info = new Info(); Status _st = new Status(); _st.setCode((short) GatewayConstants.GENERAL_ERROR); _st.setMessage(nfe.getMessage()); info.setStatus(_st); Info.Detail detail = new Info.Detail(); info.setDetail(detail); getResponse().setEntity(Util.marshal(info), MediaType.APPLICATION_XML); return; } } else { // The warm start value is mandatory!! Info info = new Info(); Status _st = new Status(); _st.setCode((short) GatewayConstants.GENERAL_ERROR); _st.setMessage("The warm start value is mandatory"); info.setStatus(_st); Info.Detail detail = new Info.Detail(); info.setDetail(detail); getResponse().setEntity(Util.marshal(info), MediaType.APPLICATION_XML); return; } if (urilistenerParam == null) { // Sync reset try { proxyGalInterface = getRestManager() .getClientObjectKey(-1, getClientInfo().getAddress()) .getGatewayInterface(); Status result = proxyGalInterface.resetDongleSync(timeout, warmStartValue); Info info = new Info(); info.setStatus(result); getResponse().setEntity(Util.marshal(info), MediaType.TEXT_XML); } catch (Exception e) { Info info = new Info(); Status _st = new Status(); _st.setCode((short) GatewayConstants.GENERAL_ERROR); _st.setMessage(e.getMessage()); info.setStatus(_st); Info.Detail detail = new Info.Detail(); info.setDetail(detail); getResponse().setEntity(Util.marshal(info), MediaType.APPLICATION_XML); return; } } else { // Async reset try { ClientResources rcmal = getRestManager() .getClientObjectKey( Util.getPortFromUriListener(urilistener), getClientInfo().getAddress()); proxyGalInterface = rcmal.getGatewayInterface(); if (!urilistener.equals("")) { rcmal.getClientEventListener().setResetDestination(urilistener); } proxyGalInterface.resetDongle(timeout, warmStartValue); Info.Detail detail = new Info.Detail(); Info infoToReturn = new Info(); Status status = new Status(); status.setCode((short) GatewayConstants.SUCCESS); infoToReturn.setStatus(status); infoToReturn.setRequestIdentifier(Util.getRequestIdentifier()); infoToReturn.setDetail(detail); getResponse().setEntity(Util.marshal(infoToReturn), MediaType.TEXT_XML); return; } catch (Exception e) { Info info = new Info(); Status _st = new Status(); _st.setCode((short) GatewayConstants.GENERAL_ERROR); _st.setMessage("The warm start value is mandatory"); info.setStatus(_st); Info.Detail detail = new Info.Detail(); info.setDetail(detail); getResponse().setEntity(Util.marshal(info), MediaType.APPLICATION_XML); return; } } }
@Override public void parseRequest( ChallengeRequest challenge, Response response, Series<Header> httpHeaders) { if (challenge.getRawValue() != null) { HeaderReader<Object> hr = new HeaderReader<Object>(challenge.getRawValue()); try { Parameter param = hr.readParameter(); while (param != null) { try { if ("realm".equals(param.getName())) { challenge.setRealm(param.getValue()); } else if ("domain".equals(param.getName())) { challenge.getDomainRefs().add(new Reference(param.getValue())); } else if ("nonce".equals(param.getName())) { challenge.setServerNonce(param.getValue()); } else if ("opaque".equals(param.getName())) { challenge.setOpaque(param.getValue()); } else if ("stale".equals(param.getName())) { challenge.setStale(Boolean.valueOf(param.getValue())); } else if ("algorithm".equals(param.getName())) { challenge.setDigestAlgorithm(param.getValue()); } else if ("qop".equals(param.getName())) { // challenge.setDigestAlgorithm(param.getValue()); } else { challenge.getParameters().add(param); } if (hr.skipValueSeparator()) { param = hr.readParameter(); } else { param = null; } } catch (Exception e) { Context.getCurrentLogger() .log(Level.WARNING, "Unable to parse the challenge request header parameter", e); } } } catch (Exception e) { Context.getCurrentLogger() .log(Level.WARNING, "Unable to parse the challenge request header parameter", e); } } }
@Override public void parseResponse( ChallengeResponse challenge, Request request, Series<Header> httpHeaders) { if (challenge.getRawValue() != null) { HeaderReader<Object> hr = new HeaderReader<Object>(challenge.getRawValue()); try { Parameter param = hr.readParameter(); while (param != null) { try { if ("username".equals(param.getName())) { challenge.setIdentifier(param.getValue()); } else if ("realm".equals(param.getName())) { challenge.setRealm(param.getValue()); } else if ("nonce".equals(param.getName())) { challenge.setServerNonce(param.getValue()); } else if ("uri".equals(param.getName())) { challenge.setDigestRef(new Reference(param.getValue())); } else if ("response".equals(param.getName())) { challenge.setSecret(param.getValue()); } else if ("algorithm".equals(param.getName())) { challenge.setDigestAlgorithm(param.getValue()); } else if ("cnonce".equals(param.getName())) { challenge.setClientNonce(param.getValue()); } else if ("opaque".equals(param.getName())) { challenge.setOpaque(param.getValue()); } else if ("qop".equals(param.getName())) { challenge.setQuality(param.getValue()); } else if ("nc".equals(param.getName())) { challenge.setServerNounceCount(Integer.valueOf(param.getValue(), 16)); } else { challenge.getParameters().add(param); } } catch (Throwable e) { Context.getCurrentLogger() .log(Level.WARNING, "Unable to parse the challenge request header parameter", e); } if (hr.skipValueSeparator()) { param = hr.readParameter(); } else { param = null; } } } catch (Exception e) { Context.getCurrentLogger() .log(Level.WARNING, "Unable to parse the challenge request header parameter", e); } } }
@Override public void formatRequest( ChallengeWriter cw, ChallengeRequest challenge, Response response, Series<Header> httpHeaders) throws IOException { if (challenge.getRealm() != null) { cw.appendQuotedChallengeParameter("realm", challenge.getRealm()); } if (!challenge.getDomainRefs().isEmpty()) { cw.append(", domain=\""); for (int i = 0; i < challenge.getDomainRefs().size(); i++) { if (i > 0) { cw.append(' '); } cw.append(challenge.getDomainRefs().get(i).toString()); } cw.append('"'); } if (challenge.getServerNonce() != null) { cw.appendQuotedChallengeParameter("nonce", challenge.getServerNonce()); } if (challenge.getOpaque() != null) { cw.appendQuotedChallengeParameter("opaque", challenge.getOpaque()); } if (challenge.isStale()) { cw.appendChallengeParameter("stale", "true"); } if (challenge.getDigestAlgorithm() != null) { cw.appendChallengeParameter("algorithm", challenge.getDigestAlgorithm()); } if (!challenge.getQualityOptions().isEmpty()) { cw.append(", qop=\""); for (int i = 0; i < challenge.getQualityOptions().size(); i++) { if (i > 0) { cw.append(','); } cw.appendToken(challenge.getQualityOptions().get(i).toString()); } cw.append('"'); } for (Parameter param : challenge.getParameters()) { if (HeaderUtils.isToken(param.getValue())) { cw.appendChallengeParameter(param); } else { cw.appendQuotedChallengeParameter(param); } } }
@Override public ContentType readValue() throws IOException { ContentType result = null; boolean readingMediaType = true; boolean readingParamName = false; boolean readingParamValue = false; StringBuilder mediaTypeBuffer = new StringBuilder(); StringBuilder paramNameBuffer = null; StringBuilder paramValueBuffer = null; Series<Parameter> parameters = null; String nextValue = readRawValue(); int nextIndex = 0; if (nextValue != null) { int nextChar = nextValue.charAt(nextIndex++); while (result == null) { if (readingMediaType) { if (nextChar == -1) { if (mediaTypeBuffer.length() > 0) { // End of metadata section // No parameters detected result = createContentType(mediaTypeBuffer, null); paramNameBuffer = new StringBuilder(); } else { // Ignore empty metadata name } } else if (nextChar == ';') { if (mediaTypeBuffer.length() > 0) { // End of mediaType section // Parameters detected readingMediaType = false; readingParamName = true; paramNameBuffer = new StringBuilder(); // [ifndef gwt] instruction parameters = new Series<Parameter>(Parameter.class); // [ifdef gwt] instruction uncomment // parameters = new // org.restlet.engine.util.ParameterSeries(); } else { throw new IOException("Empty mediaType name detected."); } } else if (HeaderUtils.isSpace(nextChar)) { // Ignore spaces } else if (HeaderUtils.isText(nextChar)) { mediaTypeBuffer.append((char) nextChar); } else { throw new IOException( "The " + (char) nextChar + " character isn't allowed in a media type name."); } } else if (readingParamName) { if (nextChar == '=') { if (paramNameBuffer.length() > 0) { // End of parameter name section readingParamName = false; readingParamValue = true; paramValueBuffer = new StringBuilder(); } else { throw new IOException("Empty parameter name detected."); } } else if (nextChar == -1) { if (paramNameBuffer.length() > 0) { // End of parameters section parameters.add(Parameter.create(paramNameBuffer, null)); result = createContentType(mediaTypeBuffer, parameters); } else if (paramNameBuffer.length() == 0) { result = createContentType(mediaTypeBuffer, parameters); } else { throw new IOException("Empty parameter name detected."); } } else if (nextChar == ';') { // End of parameter parameters.add(Parameter.create(paramNameBuffer, null)); paramNameBuffer = new StringBuilder(); readingParamName = true; readingParamValue = false; } else if (HeaderUtils.isSpace(nextChar) && (paramNameBuffer.length() == 0)) { // Ignore white spaces } else if (HeaderUtils.isTokenChar(nextChar)) { paramNameBuffer.append((char) nextChar); } else { throw new IOException( "The \"" + (char) nextChar + "\" character isn't allowed in a media type parameter name."); } } else if (readingParamValue) { if (nextChar == -1) { if (paramValueBuffer.length() > 0) { // End of parameters section parameters.add(Parameter.create(paramNameBuffer, paramValueBuffer)); result = createContentType(mediaTypeBuffer, parameters); } else { throw new IOException("Empty parameter value detected"); } } else if (nextChar == ';') { // End of parameter parameters.add(Parameter.create(paramNameBuffer, paramValueBuffer)); paramNameBuffer = new StringBuilder(); readingParamName = true; readingParamValue = false; } else if ((nextChar == '"') && (paramValueBuffer.length() == 0)) { // Parse the quoted string boolean done = false; boolean quotedPair = false; while ((!done) && (nextChar != -1)) { nextChar = (nextIndex < nextValue.length()) ? nextValue.charAt(nextIndex++) : -1; if (quotedPair) { // End of quoted pair (escape sequence) if (HeaderUtils.isText(nextChar)) { paramValueBuffer.append((char) nextChar); quotedPair = false; } else { throw new IOException( "Invalid character \"" + (char) nextChar + "\" detected in quoted string. Please check your value"); } } else if (HeaderUtils.isDoubleQuote(nextChar)) { // End of quoted string done = true; } else if (nextChar == '\\') { // Begin of quoted pair (escape sequence) quotedPair = true; } else if (HeaderUtils.isText(nextChar)) { paramValueBuffer.append((char) nextChar); } else { throw new IOException( "Invalid character \"" + (char) nextChar + "\" detected in quoted string. Please check your value"); } } } else if (HeaderUtils.isTokenChar(nextChar)) { paramValueBuffer.append((char) nextChar); } else { throw new IOException( "The \"" + (char) nextChar + "\" character isn't allowed in a media type parameter value."); } } nextChar = (nextIndex < nextValue.length()) ? nextValue.charAt(nextIndex++) : -1; } } return result; }
@Override public ContactInfo readValue() throws IOException { ContactInfo result = null; skipSpaces(); if (peek() != -1) { result = new ContactInfo(); if (peek() == '"') { result.setDisplayName(readQuotedString()); skipSpaces(); result.setReference(new Reference(readReference())); } else if (peek() == '<') { result.setReference(new Reference(readReference())); } else if (HeaderUtils.isTokenChar(peek())) { // Read value until end or value or parameter separator StringBuilder sb = null; int next = read(); while ((next != -1) && !isComma(next) && !isSemiColon(next)) { if (sb == null) { sb = new StringBuilder(); } sb.append((char) next); next = read(); } // Remove trailing spaces if (sb != null) { for (int i = sb.length() - 1; (i >= 0) && isLinearWhiteSpace(sb.charAt(i)); i--) { sb.deleteCharAt(i); } } // Unread the separator if (isComma(next) || isSemiColon(next)) { unread(); } // The last token is the reference int index = sb.lastIndexOf(" "); if (index != -1) { if (sb.charAt(index + 1) == '<') { if (sb.charAt(sb.length() - 1) == '>') { result.setReference(new Reference(sb.substring(index + 2, sb.length() - 1))); } else { throw new IOException("Unexpected end of reference. Please check your value"); } } result.setDisplayName(sb.substring(0, index).trim()); } else { result.setReference(new Reference(sb.toString())); } } } // Read address parameters. if (skipParameterSeparator()) { Parameter param = readParameter(); while (param != null) { if ("q".equals(param.getName())) { result.setQuality(PreferenceReader.readQuality(param.getValue())); } else if ("expires".equals(param.getName())) { result.setExpires(param.getValue()); } else { addParameter(result, param); } if (skipParameterSeparator()) { param = readParameter(); } else { param = null; } } } return result; }
/** * Search against all repositories using provided parameters. Note there are a few different types * of searches you can perform. If you provide the 'q' query parameter, a keyword search will be * performed. If you provide the 'g, a, v, p or c' query parameters, a maven coordinate search * will be performed. If you provide the 'cn' query parameter, a classname search will be * performed. If you provide the 'sha1' query parameter, a checksum search will be performed. * * @param q provide this param for a keyword search (g, a, v, p, c, cn, sha1 params will be * ignored). * @param sha1 provide this param for a checksum search (g, a, v, p, c, cn params will be * ignored). * @param cn provide this param for a classname search (g, a, v, p, c params will be ignored). * @param g group id to perform a maven search against (can be combined with a, v, p & c params as * well). * @param a artifact id to perform a maven search against (can be combined with g, v, p & c params * as well). * @param v version to perform a maven search against (can be combined with g, a, p & c params as * well). * @param p packaging type to perform a maven search against (can be combined with g, a, v & c * params as well). * @param c classifier to perform a maven search against (can be combined with g, a, v & p params * as well). * @param from result index to start retrieving results from. * @param count number of results to have returned to you. * @param repositoryId The repositoryId to which repository search should be narrowed. Omit if * search should be global. */ @Override @GET @ResourceMethodSignature( queryParams = { @QueryParam("q"), @QueryParam("g"), @QueryParam("a"), @QueryParam("v"), @QueryParam("p"), @QueryParam("c"), @QueryParam("cn"), @QueryParam("sha1"), @QueryParam("from"), @QueryParam("count"), @QueryParam("repositoryId") }, output = SearchResponse.class) public Object get(Context context, Request request, Response response, Variant variant) throws ResourceException { Form form = request.getResourceRef().getQueryAsForm(); final Map<String, String> terms = new HashMap<String, String>(); for (Parameter parameter : form) { terms.put(parameter.getName(), parameter.getValue()); } Integer from = null; Boolean exact = null; String repositoryId = null; Boolean expandVersion = Boolean.FALSE; Boolean collapseResults = Boolean.FALSE; if (form.getFirstValue("from") != null) { try { from = Integer.valueOf(form.getFirstValue("from")); } catch (NumberFormatException e) { from = null; } } int count = LUCENE_HIT_LIMIT; if (form.getFirstValue("count") != null) { try { // capping the possible count count = Math.min(LUCENE_HIT_LIMIT, Integer.valueOf(form.getFirstValue("count"))); } catch (NumberFormatException e) { count = LUCENE_HIT_LIMIT; } } if (form.getFirstValue("repositoryId") != null) { repositoryId = form.getFirstValue("repositoryId"); } if (form.getFirstValue("exact") != null) { exact = Boolean.valueOf(form.getFirstValue("exact")); } if (form.getFirstValue("versionexpand") != null) { expandVersion = Boolean.valueOf(form.getFirstValue("versionexpand")); } if (form.getFirstValue("collapseresults") != null) { collapseResults = Boolean.valueOf(form.getFirstValue("collapseresults")); } // A little explanation about collapseResults, that might seems little bit awkward, since // currently we have only // one column "collapsable" (the version), but before and maybe in the future that's not the // case. So, here is // it: // the "collapseResults" is just a flag "do we allow collapse at all". It is just a shorthand to // turn on or off // collapse generally // Let's assume we have columns colA, colB and colC collapsable. So, instead saying // expandColA=true,expandColB=true,expandColC=true, // it is just easy to say collapseresults=false // BUT, if collapseresults=true is sent by client, even then an "override" will happen if there // is actually NO // ROW to collapse! // So: collapseresults=false EQUALS-TO expandColA=true & expandColB=true & expandColC=true if (collapseResults) { // here we would like to have ANDed all the collapsable column flags and negated the result // currently we collapseResults = !(true && expandVersion); // && expandColA && expandColB; } IteratorSearchResponse searchResult = null; SearchNGResponse result = new SearchNGResponse(); int runCount = 0; while (runCount < RETRIES) { try { List<ArtifactInfoFilter> filters = new ArrayList<ArtifactInfoFilter>(); // we need to save this reference to later SystemWideLatestVersionCollector systemWideCollector = new SystemWideLatestVersionCollector(); filters.add(systemWideCollector); RepositoryWideLatestVersionCollector repositoryWideCollector = null; if (collapseResults) { repositoryWideCollector = new RepositoryWideLatestVersionCollector(); filters.add(repositoryWideCollector); } try { searchResult = searchByTerms( terms, repositoryId, from, count, exact, expandVersion, collapseResults, filters, searchers); if (searchResult == null) { collapseResults = false; continue; } else { repackIteratorSearchResponse( request, terms, result, collapseResults, from, count, searchResult, systemWideCollector, repositoryWideCollector); if (!result.isTooManyResults()) { // if we had collapseResults ON, and the totalHits are larger than actual (filtered) // results, and the actual result count is below COLLAPSE_OVERRIDE_TRESHOLD, // and full result set is smaller than HIT_LIMIT // then repeat without collapse if (collapseResults && result.getData().size() < searchResult.getTotalHitsCount() && result.getData().size() < COLLAPSE_OVERRIDE_TRESHOLD && searchResult.getTotalHitsCount() < GA_HIT_LIMIT) { collapseResults = false; continue; } } } } catch (IOException e) { throw new ResourceException(Status.SERVER_ERROR_INTERNAL, e.getMessage(), e); } // we came here, so we break the while-loop, we got what we need break; } catch (NoSuchRepositoryException e) { throw new ResourceException( Status.CLIENT_ERROR_BAD_REQUEST, "Repository to be searched does not exists!", e); } catch (AlreadyClosedException e) { runCount++; getLogger() .info( "NexusIndexer issue (NEXUS-3702), we got AlreadyClosedException that happens when Reindexing or other \"indexer intensive\" task is running on instance while searching! Redoing search again."); if (getLogger().isDebugEnabled()) { // just keep it silent (DEBUG) getLogger().debug("Got AlreadyClosedException exception!", e); } result.setData(null); } } if (result.getData() == null) { try { repackIteratorSearchResponse( request, terms, result, collapseResults, from, count, IteratorSearchResponse.empty(null), null, null); } catch (NoSuchRepositoryException e) { // will not happen } catch (IOException e) { // will not happen } getLogger() .info( "Nexus issue (NEXUS-3702): Was unable to perform search " + RETRIES + " times, giving up, and lying about TooManyResults. Please retry to reproduce this with DEBUG logs and report this issue!"); } return result; }