001: /*
002: * Copyright 2005-2007 Noelios Consulting.
003: *
004: * The contents of this file are subject to the terms of the Common Development
005: * and Distribution License (the "License"). You may not use this file except in
006: * compliance with the License.
007: *
008: * You can obtain a copy of the license at
009: * http://www.opensource.org/licenses/cddl1.txt See the License for the specific
010: * language governing permissions and limitations under the License.
011: *
012: * When distributing Covered Code, include this CDDL HEADER in each file and
013: * include the License file at http://www.opensource.org/licenses/cddl1.txt If
014: * applicable, add the following below this CDDL HEADER, with the fields
015: * enclosed by brackets "[]" replaced with your own identifying information:
016: * Portions Copyright [yyyy] [name of copyright owner]
017: */
018:
019: package com.noelios.restlet;
020:
021: import java.io.BufferedReader;
022: import java.io.IOException;
023: import java.io.InputStreamReader;
024: import java.net.URL;
025: import java.util.ArrayList;
026: import java.util.Enumeration;
027: import java.util.Iterator;
028: import java.util.List;
029: import java.util.logging.Level;
030: import java.util.logging.Logger;
031:
032: import org.restlet.Application;
033: import org.restlet.Client;
034: import org.restlet.Component;
035: import org.restlet.Context;
036: import org.restlet.Directory;
037: import org.restlet.Server;
038: import org.restlet.data.CharacterSet;
039: import org.restlet.data.ClientInfo;
040: import org.restlet.data.Form;
041: import org.restlet.data.Language;
042: import org.restlet.data.MediaType;
043: import org.restlet.data.Parameter;
044: import org.restlet.data.Preference;
045: import org.restlet.data.Protocol;
046: import org.restlet.data.Request;
047: import org.restlet.data.Response;
048: import org.restlet.resource.Representation;
049: import org.restlet.resource.Resource;
050: import org.restlet.resource.Variant;
051: import org.restlet.util.Helper;
052:
053: import com.noelios.restlet.application.ApplicationHelper;
054: import com.noelios.restlet.component.ComponentHelper;
055: import com.noelios.restlet.local.DirectoryResource;
056: import com.noelios.restlet.util.FormUtils;
057:
058: /**
059: * Restlet factory supported by the engine.
060: *
061: * @author Jerome Louvel (contact@noelios.com)
062: */
063: public class Engine extends org.restlet.util.Engine {
064: /** Obtain a suitable logger. */
065: private static Logger logger = Logger.getLogger(Engine.class
066: .getCanonicalName());
067:
068: /** Complete version. */
069: public static final String VERSION = org.restlet.util.Engine.VERSION;
070:
071: /** Complete version header. */
072: public static final String VERSION_HEADER = "Noelios-Restlet-Engine/"
073: + VERSION;
074:
075: /**
076: * Registers a new Noelios Restlet Engine.
077: */
078: public static void register() {
079: Engine.setInstance(new Engine());
080: }
081:
082: /** List of available client connectors. */
083: private List<ConnectorHelper> registeredClients;
084:
085: /** List of available server connectors. */
086: private List<ConnectorHelper> registeredServers;
087:
088: /**
089: * Constructor that will automatically attempt to discover connectors.
090: */
091: @SuppressWarnings("unchecked")
092: public Engine() {
093: this (true);
094: }
095:
096: /**
097: * Constructor.
098: *
099: * @param discoverConnectors
100: * True if connectors should be automatically discovered.
101: */
102: @SuppressWarnings("unchecked")
103: public Engine(boolean discoverConnectors) {
104: if (discoverConnectors) {
105: // Find the factory class name
106: String line = null;
107: String provider = null;
108:
109: // Find the factory class name
110: ClassLoader cl = org.restlet.util.Engine.getClassLoader();
111: URL configURL;
112:
113: // Register the client connector providers
114: try {
115: for (Enumeration<URL> configUrls = cl
116: .getResources("META-INF/services/com.noelios.restlet.ClientHelper"); configUrls
117: .hasMoreElements();) {
118: configURL = configUrls.nextElement();
119:
120: BufferedReader reader = null;
121: try {
122: reader = new BufferedReader(
123: new InputStreamReader(configURL
124: .openStream(), "utf-8"));
125: line = reader.readLine();
126:
127: while (line != null) {
128: provider = getProviderClassName(line);
129:
130: if ((provider != null)
131: && (!provider.equals(""))) {
132: // Instantiate the factory
133: try {
134: Class<? extends ConnectorHelper> providerClass = (Class<? extends ConnectorHelper>) Class
135: .forName(provider);
136: getRegisteredClients()
137: .add(
138: providerClass
139: .getConstructor(
140: Client.class)
141: .newInstance(
142: (Client) null));
143: } catch (Exception e) {
144: logger.log(Level.SEVERE,
145: "Unable to register the client connector "
146: + provider, e);
147: }
148: }
149:
150: line = reader.readLine();
151: }
152: } catch (IOException e) {
153: logger.log(Level.SEVERE,
154: "Unable to read the provider descriptor: "
155: + configURL.toString());
156: } finally {
157: if (reader != null)
158: reader.close();
159: }
160: }
161: } catch (IOException ioe) {
162: logger
163: .log(
164: Level.SEVERE,
165: "Exception while detecting the client connectors.",
166: ioe);
167: }
168:
169: // Register the server connector providers
170: try {
171: for (Enumeration<URL> configUrls = cl
172: .getResources("META-INF/services/com.noelios.restlet.ServerHelper"); configUrls
173: .hasMoreElements();) {
174: configURL = configUrls.nextElement();
175:
176: BufferedReader reader = null;
177: try {
178: reader = new BufferedReader(
179: new InputStreamReader(configURL
180: .openStream(), "utf-8"));
181: line = reader.readLine();
182:
183: while (line != null) {
184: provider = getProviderClassName(line);
185:
186: if ((provider != null)
187: && (!provider.equals(""))) {
188: // Instantiate the factory
189: try {
190: Class<? extends ConnectorHelper> providerClass = (Class<? extends ConnectorHelper>) Class
191: .forName(provider);
192: getRegisteredServers()
193: .add(
194: providerClass
195: .getConstructor(
196: Server.class)
197: .newInstance(
198: (Server) null));
199: } catch (Exception e) {
200: logger.log(Level.SEVERE,
201: "Unable to register the server connector "
202: + provider, e);
203: }
204: }
205:
206: line = reader.readLine();
207: }
208: } catch (IOException e) {
209: logger.log(Level.SEVERE,
210: "Unable to read the provider descriptor: "
211: + configURL.toString());
212: } finally {
213: if (reader != null)
214: reader.close();
215: }
216: }
217: } catch (IOException ioe) {
218: logger
219: .log(
220: Level.SEVERE,
221: "Exception while detecting the client connectors.",
222: ioe);
223: }
224: }
225: }
226:
227: /**
228: * Returns the list of available client connectors.
229: *
230: * @return The list of available client connectors.
231: */
232: public List<ConnectorHelper> getRegisteredClients() {
233: if (this .registeredClients == null)
234: this .registeredClients = new ArrayList<ConnectorHelper>();
235: return this .registeredClients;
236: }
237:
238: /**
239: * Returns the list of available server connectors.
240: *
241: * @return The list of available server connectors.
242: */
243: public List<ConnectorHelper> getRegisteredServers() {
244: if (this .registeredServers == null)
245: this .registeredServers = new ArrayList<ConnectorHelper>();
246: return this .registeredServers;
247: }
248:
249: /**
250: * Creates a directory resource.
251: *
252: * @param handler
253: * The parent directory handler.
254: * @param request
255: * The request to handle.
256: * @param response
257: * The response to return.
258: * @return A new directory resource.
259: * @throws IOException
260: */
261: public Resource createDirectoryResource(Directory handler,
262: Request request, Response response) throws IOException {
263: return new DirectoryResource(handler, request, response);
264: }
265:
266: /**
267: * Creates a new helper for a given component.
268: *
269: * @param application
270: * The application to help.
271: * @param parentContext
272: * The parent context, typically the component's context.
273: * @return The new helper.
274: */
275: public Helper createHelper(Application application,
276: Context parentContext) {
277: return new ApplicationHelper(application, parentContext);
278: }
279:
280: /**
281: * Creates a new helper for a given client connector.
282: *
283: * @param client
284: * The client to help.
285: * @return The new helper.
286: */
287: public Helper createHelper(Client client) {
288: Helper result = null;
289:
290: if (client.getProtocols().size() > 0) {
291: ConnectorHelper connector = null;
292: for (Iterator<ConnectorHelper> iter = getRegisteredClients()
293: .iterator(); (result == null) && iter.hasNext();) {
294: connector = iter.next();
295:
296: if (connector.getProtocols().containsAll(
297: client.getProtocols())) {
298: try {
299: result = connector.getClass().getConstructor(
300: Client.class).newInstance(client);
301: } catch (Exception e) {
302: logger
303: .log(
304: Level.SEVERE,
305: "Exception while instantiation the client connector.",
306: e);
307: }
308: }
309: }
310:
311: if (result == null) {
312: // Couldn't find a matching connector
313: StringBuilder sb = new StringBuilder();
314: sb
315: .append("No available client connector supports the required protocols: ");
316:
317: for (Protocol p : client.getProtocols()) {
318: sb.append(p.getName()).append(" ");
319: }
320:
321: sb
322: .append(". Please add the JAR of a matching connector to your classpath.");
323:
324: logger.log(Level.WARNING, sb.toString());
325: }
326: }
327:
328: return result;
329: }
330:
331: /**
332: * Creates a new helper for a given component.
333: *
334: * @param component
335: * The component to help.
336: * @return The new helper.
337: */
338: public Helper createHelper(Component component) {
339: return new ComponentHelper(component);
340: }
341:
342: /**
343: * Creates a new helper for a given server connector.
344: *
345: * @param server
346: * The server to help.
347: * @return The new helper.
348: */
349: public Helper createHelper(Server server) {
350: Helper result = null;
351:
352: if (server.getProtocols().size() > 0) {
353: ConnectorHelper connector = null;
354: for (Iterator<ConnectorHelper> iter = getRegisteredServers()
355: .iterator(); (result == null) && iter.hasNext();) {
356: connector = iter.next();
357:
358: if (connector.getProtocols().containsAll(
359: server.getProtocols())) {
360: try {
361: result = connector.getClass().getConstructor(
362: Server.class).newInstance(server);
363: } catch (Exception e) {
364: logger
365: .log(
366: Level.SEVERE,
367: "Exception while instantiation the server connector.",
368: e);
369: }
370: }
371: }
372:
373: if (result == null) {
374: // Couldn't find a matching connector
375: StringBuilder sb = new StringBuilder();
376: sb
377: .append("No available server connector supports the required protocols: ");
378:
379: for (Protocol p : server.getProtocols()) {
380: sb.append(p.getName()).append(" ");
381: }
382:
383: sb
384: .append(". Please add the JAR of a matching connector to your classpath.");
385:
386: logger.log(Level.WARNING, sb.toString());
387: }
388: }
389:
390: return result;
391: }
392:
393: /**
394: * Parses the "java.version" system property and returns the first digit of
395: * the version number of the Java Runtime Environment (e.g. "1" for
396: * "1.3.0").
397: *
398: * @see <a href="http://java.sun.com/j2se/versioning_naming.html">Official
399: * Java versioning</a>
400: * @return The major version number of the Java Runtime Environment.
401: */
402: public static int getJavaMajorVersion() {
403: int result;
404: String javaVersion = System.getProperty("java.version");
405: try {
406: result = Integer.parseInt(javaVersion.substring(0,
407: javaVersion.indexOf(".")));
408: } catch (Exception e) {
409: result = 0;
410: }
411:
412: return result;
413: }
414:
415: /**
416: * Parses the "java.version" system property and returns the second digit of
417: * the version number of the Java Runtime Environment (e.g. "3" for
418: * "1.3.0").
419: *
420: * @see <a href="http://java.sun.com/j2se/versioning_naming.html">Official
421: * Java versioning</a>
422: * @return The minor version number of the Java Runtime Environment.
423: */
424: public static int getJavaMinorVersion() {
425: int result;
426: String javaVersion = System.getProperty("java.version");
427: try {
428: result = Integer.parseInt(javaVersion.split("\\.")[1]);
429: } catch (Exception e) {
430: result = 0;
431: }
432:
433: return result;
434: }
435:
436: /**
437: * Parses the "java.version" system property and returns the update release
438: * number of the Java Runtime Environment (e.g. "10" for "1.3.0_10").
439: *
440: * @see <a href="http://java.sun.com/j2se/versioning_naming.html">Official
441: * Java versioning</a>
442: * @return The release number of the Java Runtime Environment or 0 if it
443: * does not exist.
444: */
445: public static int getJavaUpdateVersion() {
446: int result;
447: String javaVersion = System.getProperty("java.version");
448: try {
449: result = Integer.parseInt(javaVersion.substring(javaVersion
450: .indexOf('_') + 1));
451: } catch (Exception e) {
452: result = 0;
453: }
454:
455: return result;
456: }
457:
458: /**
459: * Returns the preferred variant representation for a given resource
460: * according the the client preferences.
461: *
462: * @param client
463: * The client preferences.
464: * @param variants
465: * The list of variants to compare.
466: * @return The preferred variant.
467: * @see <a
468: * href="http://httpd.apache.org/docs/2.2/en/content-negotiation.html#algorithm">Apache
469: * content negotiation algorithm</a>
470: */
471: public Variant getPreferredVariant(ClientInfo client,
472: List<Variant> variants, Language defaultLanguage) {
473: if (variants == null) {
474: return null;
475: } else {
476: List<Language> variantLanguages = null;
477: MediaType variantMediaType = null;
478:
479: boolean compatibleLanguage = false;
480: boolean compatibleMediaType = false;
481:
482: Variant currentVariant = null;
483: Variant bestVariant = null;
484:
485: Preference<Language> currentLanguagePref = null;
486: Preference<Language> bestLanguagePref = null;
487: Preference<MediaType> currentMediaTypePref = null;
488: Preference<MediaType> bestMediaTypePref = null;
489:
490: float bestQuality = 0;
491: float bestLanguageScore = 0;
492: float bestMediaTypeScore = 0;
493:
494: // If no language preference is defined or even none matches, we
495: // want to make sure that at least a variant can be returned.
496: // Based on experience, it appears that browsers are often
497: // misconfigured and don't expose all the languages actually
498: // understood by end users.
499: // Thus, a few other preferences are added to the user's ones:
500: // - primary languages inferred from and sorted according to the
501: // user's preferences with quality between 0.005 and 0.006
502: // - default language (if any) with quality 0.003
503: // - primary language of the default language (if available) with
504: // quality 0.002
505: // - all languages with quality 0.001
506: List<Preference<Language>> languagePrefs = client
507: .getAcceptedLanguages();
508: List<Preference<Language>> primaryLanguagePrefs = new ArrayList<Preference<Language>>();
509: // A default language preference is defined with a better weight
510: // than the "All languages" preference
511: Preference<Language> defaultLanguagePref = ((defaultLanguage == null) ? null
512: : new Preference<Language>(defaultLanguage, 0.003f));
513: Preference<Language> allLanguagesPref = new Preference<Language>(
514: Language.ALL, 0.001f);
515:
516: if (languagePrefs.isEmpty()) {
517: // All languages accepted.
518: languagePrefs
519: .add(new Preference<Language>(Language.ALL));
520: } else {
521: // Get the primary language preferences that are not currently
522: // accepted by the client
523: List<String> list = new ArrayList<String>();
524: for (Preference<Language> preference : languagePrefs) {
525: Language language = preference.getMetadata();
526: if (!language.getSubTags().isEmpty()) {
527: if (!list.contains(language.getPrimaryTag())) {
528: list.add(language.getPrimaryTag());
529: primaryLanguagePrefs
530: .add(new Preference<Language>(
531: new Language(language
532: .getPrimaryTag()),
533: 0.005f + (0.001f * preference
534: .getQuality())));
535: }
536: }
537: }
538: // If the default language is a "primary" language but is not
539: // present in the list of all primary languages, add it.
540: if (defaultLanguage != null
541: && !defaultLanguage.getSubTags().isEmpty()) {
542: if (!list.contains(defaultLanguage.getPrimaryTag())) {
543: primaryLanguagePrefs
544: .add(new Preference<Language>(
545: new Language(defaultLanguage
546: .getPrimaryTag()),
547: 0.002f));
548: }
549: }
550:
551: }
552:
553: // Client preferences are altered
554: languagePrefs.addAll(primaryLanguagePrefs);
555: if (defaultLanguagePref != null) {
556: languagePrefs.add(defaultLanguagePref);
557: // In this case, if the client adds the "all languages"
558: // preference, the latter is removed, in order to support the
559: // default preference defined by the server
560: List<Preference<Language>> list = new ArrayList<Preference<Language>>();
561: for (Preference<Language> preference : languagePrefs) {
562: Language language = preference.getMetadata();
563: if (!language.equals(Language.ALL)) {
564: list.add(preference);
565: }
566: }
567: languagePrefs = list;
568: }
569: languagePrefs.add(allLanguagesPref);
570:
571: // For each available variant, we will compute the negotiation score
572: // which is dependant on the language score and on the media type
573: // score
574: for (Iterator<Variant> iter1 = variants.iterator(); iter1
575: .hasNext();) {
576: currentVariant = iter1.next();
577: variantLanguages = currentVariant.getLanguages();
578: variantMediaType = currentVariant.getMediaType();
579:
580: // All languages of the current variant are scored.
581: for (Language variantLanguage : variantLanguages) {
582: // For each language preference defined in the call
583: // Calculate the score and remember the best scoring
584: // preference
585: for (Iterator<Preference<Language>> iter2 = languagePrefs
586: .iterator(); (variantLanguage != null)
587: && iter2.hasNext();) {
588: currentLanguagePref = iter2.next();
589: float currentScore = getScore(variantLanguage,
590: currentLanguagePref.getMetadata());
591: boolean compatiblePref = (currentScore != -1.0f);
592: // 3) Do we have a better preference?
593: // currentScore *= currentPref.getQuality();
594: if (compatiblePref
595: && ((bestLanguagePref == null) || (currentScore > bestLanguageScore))) {
596: bestLanguagePref = currentLanguagePref;
597: bestLanguageScore = currentScore;
598: }
599: }
600: }
601:
602: // Are the preferences compatible with the current variant
603: // language?
604: compatibleLanguage = (variantLanguages.isEmpty())
605: || (bestLanguagePref != null);
606:
607: // If no media type preference is defined, assume that all media
608: // types are acceptable
609: List<Preference<MediaType>> mediaTypePrefs = client
610: .getAcceptedMediaTypes();
611: if (mediaTypePrefs.size() == 0)
612: mediaTypePrefs.add(new Preference<MediaType>(
613: MediaType.ALL));
614:
615: // For each media range preference defined in the call
616: // Calculate the score and remember the best scoring preference
617: for (Iterator<Preference<MediaType>> iter2 = mediaTypePrefs
618: .iterator(); compatibleLanguage
619: && iter2.hasNext();) {
620: currentMediaTypePref = iter2.next();
621: float currentScore = getScore(variantMediaType,
622: currentMediaTypePref.getMetadata());
623: boolean compatiblePref = (currentScore != -1.0f);
624: // 3) Do we have a better preference?
625: // currentScore *= currentPref.getQuality();
626: if (compatiblePref
627: && ((bestMediaTypePref == null) || (currentScore > bestMediaTypeScore))) {
628: bestMediaTypePref = currentMediaTypePref;
629: bestMediaTypeScore = currentScore;
630: }
631:
632: }
633:
634: // Are the preferences compatible with the current media type?
635: compatibleMediaType = (variantMediaType == null)
636: || (bestMediaTypePref != null);
637:
638: if (compatibleLanguage && compatibleMediaType) {
639: // Do we have a compatible media type?
640: float currentQuality = 0;
641: if (bestLanguagePref != null) {
642: currentQuality += (bestLanguagePref
643: .getQuality() * 10F);
644: } else if (!variantLanguages.isEmpty()) {
645: currentQuality += 0.1F * 10F;
646: }
647:
648: if (bestMediaTypePref != null) {
649: // So, let's conclude on the current variant, its
650: // quality
651: currentQuality += bestMediaTypePref
652: .getQuality();
653: }
654:
655: if (bestVariant == null) {
656: bestVariant = currentVariant;
657: bestQuality = currentQuality;
658: } else if (currentQuality > bestQuality) {
659: bestVariant = currentVariant;
660: bestQuality = currentQuality;
661: }
662: }
663:
664: // Reset the preference variables
665: bestLanguagePref = null;
666: bestLanguageScore = 0;
667: bestMediaTypePref = null;
668: bestMediaTypeScore = 0;
669: }
670:
671: return bestVariant;
672: }
673: }
674:
675: /**
676: * Returns a matching score between 2 Languages
677: *
678: * @param variantLanguage
679: * @param preferenceLanguage
680: * @return the positive matching score or -1 if the languages are not
681: * compatible
682: */
683: private float getScore(Language variantLanguage,
684: Language preferenceLanguage) {
685: float score = 0.0f;
686: boolean compatibleLang = true;
687:
688: // 1) Compare the main tag
689: if (variantLanguage.getPrimaryTag().equalsIgnoreCase(
690: preferenceLanguage.getPrimaryTag())) {
691: score += 100;
692: } else if (!preferenceLanguage.getPrimaryTag().equals("*")) {
693: compatibleLang = false;
694: } else if (!preferenceLanguage.getSubTags().isEmpty()) {
695: // Only "*" is an acceptable language range
696: compatibleLang = false;
697: } else {
698: // The valid "*" range has the lowest valid score
699: score++;
700: }
701:
702: if (compatibleLang) {
703: // 2) Compare the sub tags
704: if ((preferenceLanguage.getSubTags().isEmpty())
705: || (variantLanguage.getSubTags().isEmpty())) {
706: if (variantLanguage.getSubTags().isEmpty()
707: && preferenceLanguage.getSubTags().isEmpty()) {
708: score += 10;
709: } else {
710: // Don't change the score
711: }
712: } else {
713: int maxSize = Math.min(preferenceLanguage.getSubTags()
714: .size(), variantLanguage.getSubTags().size());
715: for (int i = 0; i < maxSize && compatibleLang; i++) {
716: if (preferenceLanguage
717: .getSubTags()
718: .get(i)
719: .equalsIgnoreCase(
720: variantLanguage.getSubTags().get(i))) {
721: // Each subtag contribution to the score
722: // is getting less and less important
723: score += Math.pow(10, 1 - i);
724: } else {
725: // SubTags are different
726: compatibleLang = false;
727: }
728: }
729: }
730: }
731:
732: return (compatibleLang ? score : -1.0f);
733: }
734:
735: /**
736: * Returns a matching score between 2 Media types
737: *
738: * @param variantMediaType
739: * @param preferenceMediaType
740: * @return the positive matching score or -1 if the media types are not
741: * compatible
742: */
743: private float getScore(MediaType variantMediaType,
744: MediaType preferenceMediaType) {
745: float score = 0.0f;
746: boolean comptabibleMediaType = true;
747:
748: // 1) Compare the main types
749: if (preferenceMediaType.getMainType().equals(
750: variantMediaType.getMainType())) {
751: score += 1000;
752: } else if (!preferenceMediaType.getMainType().equals("*")) {
753: comptabibleMediaType = false;
754: } else if (!preferenceMediaType.getSubType().equals("*")) {
755: // Ranges such as "*/html" are not supported
756: // Only "*/*" is acceptable in this case
757: comptabibleMediaType = false;
758: }
759:
760: if (comptabibleMediaType) {
761: // 2) Compare the sub types
762: if (variantMediaType.getSubType().equals(
763: preferenceMediaType.getSubType())) {
764: score += 100;
765: } else if (!preferenceMediaType.getSubType().equals("*")) {
766: // Subtype are different
767: comptabibleMediaType = false;
768: }
769:
770: if (comptabibleMediaType
771: && (variantMediaType.getParameters() != null)) {
772: // 3) Compare the parameters
773: // If current media type is compatible with the
774: // current media range then the parameters need to
775: // be checked too
776: for (Iterator<Parameter> iter3 = variantMediaType
777: .getParameters().iterator(); iter3.hasNext();) {
778: Parameter currentParam = iter3.next();
779:
780: if (isParameterFound(currentParam,
781: preferenceMediaType)) {
782: score++;
783: }
784: }
785: }
786:
787: }
788: return (comptabibleMediaType ? score : -1.0f);
789: }
790:
791: /**
792: * Parses a line to extract the provider class name.
793: *
794: * @param line
795: * The line to parse.
796: * @return The provider's class name or an empty string.
797: */
798: private String getProviderClassName(String line) {
799: int index = line.indexOf('#');
800: if (index != -1)
801: line = line.substring(0, index);
802: return line.trim();
803: }
804:
805: /**
806: * Indicates if the searched parameter is specified in the given media
807: * range.
808: *
809: * @param searchedParam
810: * The searched parameter.
811: * @param mediaRange
812: * The media range to inspect.
813: * @return True if the searched parameter is specified in the given media
814: * range.
815: */
816: private boolean isParameterFound(Parameter searchedParam,
817: MediaType mediaRange) {
818: boolean result = false;
819:
820: for (Iterator<Parameter> iter = mediaRange.getParameters()
821: .iterator(); !result && iter.hasNext();) {
822: result = searchedParam.equals((Parameter) iter.next());
823: }
824:
825: return result;
826: }
827:
828: /**
829: * Parses an URL encoded Web form.
830: *
831: * @param logger
832: * The logger to use.
833: * @param form
834: * The target form.
835: * @param webForm
836: * The posted form.
837: */
838: public void parse(Logger logger, Form form, Representation webForm) {
839: if (webForm != null) {
840: FormUtils.parsePost(logger, form, webForm);
841: }
842: }
843:
844: /**
845: * Parses an URL encoded query string into a given form.
846: *
847: * @param logger
848: * The logger to use.
849: * @param form
850: * The target form.
851: * @param queryString
852: * Query string.
853: * @param characterSet
854: * The supported character encoding.
855: */
856: public void parse(Logger logger, Form form, String queryString,
857: CharacterSet characterSet) {
858: if ((queryString != null) && !queryString.equals("")) {
859: FormUtils.parseQuery(logger, form, queryString,
860: characterSet);
861: }
862: }
863:
864: }
|