001: /**
002: * $Id: FEDIClientDetector.java,v 1.3 2004/03/30 02:59:28 sathyakn Exp $
003: * Allrights reserved. Use of this product is subject to license terms.
004: * Federal Acquisitions: Commercial Software -- Government Users Subject
005: * to Standard License Terms and Conditions.
006: *
007: * Sun, Sun Microsystems, the Sun logo, and Sun ONE are trademarks or
008: * registered trademarks of Sun Microsystems,Inc. in the United States
009: * and other countries.
010: */
011:
012: /**
013: * <p>The <CODE>FEDIClientDetector</CODE> class implements the client detection
014: * algorithm for supporting jsr188 in the wireless portal server using the
015: * jsr188 RI.
016: */package com.sun.mobile.cdm;
017:
018: import java.io.File;
019: import java.io.FileInputStream;
020:
021: import java.util.Set;
022: import java.util.HashSet;
023: import java.util.Map;
024: import java.util.HashMap;
025: import java.util.Iterator;
026: import java.util.Collection;
027: import java.util.StringTokenizer;
028: import java.util.logging.Level;
029: import java.util.logging.Logger;
030: import java.util.logging.LogManager;
031:
032: import javax.servlet.http.HttpServletRequest;
033:
034: import com.iplanet.services.cdm.Client;
035: import com.iplanet.services.cdm.ClientDetectionException;
036:
037: import javax.ccpp.Attribute;
038: import javax.ccpp.SetAttribute;
039: import javax.ccpp.SequenceAttribute;
040:
041: import javax.ccpp.Profile;
042: import javax.ccpp.ProfileFactory;
043: import javax.ccpp.ProfileFragmentFactory;
044:
045: import com.sun.ccpp.DescriptionManager;
046: import com.sun.ccpp.ProfileFactoryImpl;
047: import com.sun.ccpp.ProfileFragmentFactoryImpl;
048:
049: import com.sun.mobile.util.MAPConfigProperties;
050:
051: public class FEDIClientDetector extends CCPPClientDetector {
052: private String this ClassName = null; // for debug
053:
054: //
055: // The properties (keys) to fetch from MapConfig.properties
056: //
057: public static final String DEF_SCHEMA_FILE = "/vocabularies/vocabulary.xsd";
058:
059: public static final String DEF_VOCAB_DEFNS = "/vocabularies/universalvocab.xml";
060:
061: private static String CONFIG_ROOT = MAPConfigProperties.get(
062: "fediConfigRoot", null);
063:
064: private static final String SCHEMA_FILE = MAPConfigProperties.get(
065: "schemaFile", DEF_SCHEMA_FILE);
066:
067: private static final String VOCAB_DEFNS = MAPConfigProperties.get(
068: "vocabularyDefinitions", DEF_VOCAB_DEFNS);
069:
070: //
071: // property in MAPConfig.properties - stores the profile in the
072: // Client Object. as the second element in the iteration.
073: //
074: private static final String STORE_PROFILE_IN = MAPConfigProperties
075: .get("storeProfileInClient", null);
076:
077: //
078: // FEDI Factory Objects
079: //
080: private static ProfileFactory profileFactory = null;
081:
082: static {
083: if (CONFIG_ROOT == null) {
084: //
085: // Cannot add vocabularies !
086: //
087: debug
088: .error("Could not get 'fediConfigRoot' from properties file: ");
089: } else {
090: Logger logger = Logger.getLogger("com.sun.ccpp.logger");
091: logger.setLevel(Level.ALL);
092: DebugHandler dh = new DebugHandler(debug);
093: logger.addHandler(dh);
094:
095: ProfileFactory pf = ProfileFactoryImpl.getInstance();
096: ProfileFactory.setInstance(pf);
097:
098: ProfileFragmentFactory pff = ProfileFragmentFactoryImpl
099: .getInstance();
100: ProfileFragmentFactory.setInstance(pff);
101:
102: try {
103: String schemaFile = CONFIG_ROOT + SCHEMA_FILE;
104: File schema = new File(schemaFile);
105:
106: DescriptionManager.setSchema(schema);
107: DescriptionManager dm = DescriptionManager
108: .getInstance();
109:
110: String[] vocabFiles = parseString(VOCAB_DEFNS);
111: for (int i = 0; i < vocabFiles.length; i++) {
112: File vocab = new File(vocabFiles[i]);
113: dm.addVocabulary(vocab);
114: }
115:
116: profileFactory = ProfileFactory.getInstance();
117: } catch (Throwable e) {
118: debug.warning("Could not create Profile Object", e);
119: e.printStackTrace();
120: }
121: }
122: }
123:
124: private static String[] parseString(String data) {
125: StringTokenizer st = new StringTokenizer(data); // use <space>
126: String[] arr = new String[st.countTokens()];
127: for (int i = 0; st.hasMoreTokens(); i++) {
128: arr[i] = CONFIG_ROOT + st.nextToken();
129: }
130:
131: return (arr);
132: }
133:
134: //
135: // Constructor
136: //
137: public FEDIClientDetector() {
138: this ClassName = getClass().getName();
139: }
140:
141: protected Map getMergedUAProfile(Client client,
142: HttpServletRequest request) throws ClientDetectionException {
143: if (profileFactory == null) {
144: throw new ClientDetectionException(this ClassName
145: + " :: ProfileFactory Object not Initialized.");
146: }
147:
148: Profile profile = null;
149: try {
150: profile = profileFactory.newProfile(request);
151: } catch (Exception e) {
152: debug
153: .warning(
154: this ClassName + ": Merge Profile failed: ",
155: e);
156: }
157:
158: Set attrs = null;
159: if ((profile == null)
160: || ((attrs = profile.getAttributes()) == null)) {
161: debug.warning(this ClassName
162: + ": Merge failed: Profile object is empty");
163:
164: return null;
165: }
166:
167: if (debug.messageEnabled()) {
168: debug.message("PROFILE STR:" + profile.toString());
169: }
170:
171: //
172: // Convert the Profile to a HashMap
173: //
174: Map profMap = new HashMap();
175: Iterator itr = attrs.iterator();
176: while (itr.hasNext()) {
177: Attribute attr = (Attribute) itr.next();
178: String propertyName = attr.getName();
179: Set values = getPropertiesFromUAProf(attr, propertyName);
180:
181: if (values != null) {
182: /**
183: * Since we flatten out the namespace (by calling
184: * Attribute::getName()), if we find Attributes with the
185: * same localname, qualify the second one so we dont
186: * overwrite the first.
187: */
188: if (profMap.containsKey(propertyName)) {
189: propertyName = attr.getDescription().getURI();
190: }
191:
192: profMap.put(propertyName, values);
193: }
194: }
195:
196: if (STORE_PROFILE_IN != null) {
197: /**
198: * To get the ccpp Profile object, define a property value
199: * in MAPConfig.properties to store the Profile in, with key=
200: * storeProfileInClient. Ex: storeProfileInClient=javax.ccpp.Profile
201: * This cdm stores the Profile in the client property with the name -
202: * javax.ccpp.Profile and in the second element of the Set. Second
203: * element because the Client.getProperty() gets the first property and
204: * casts it to a String and we dont want to run into ClassCastExceptions.
205: *
206: * To get the property call Client.getProperties("javax.ccpp.Profile")
207: * and iterate to reach the second element.
208: */
209: Set prop = new OrderedSet(2);
210: prop.add(STORE_PROFILE_IN); // first dummy element
211: prop.add(profile);
212:
213: profMap.put(STORE_PROFILE_IN, prop);
214: }
215:
216: return profMap;
217: }
218:
219: /**
220: * Wrapper to catch all Exceptions and return null
221: */
222: private Set getPropertiesFromUAProf(Attribute p, String name) {
223: if ((p == null) || (name == null)) {
224: return null;
225: }
226:
227: Set properties = null;
228: try {
229: if (p instanceof SetAttribute) {
230: Collection c = (Collection) p.getValue();
231: if (c != null) {
232: Iterator itr = c.iterator();
233: properties = new HashSet(c.size());
234: while (itr.hasNext()) {
235: String s = (itr.next()).toString();
236: properties.add(s);
237: }
238: }
239: } else if (p instanceof SequenceAttribute) {
240: Collection c = (Collection) p.getValue();
241: if (c != null) {
242: properties = new OrderedSet(c);
243: }
244: } else {
245: String s = p.toString();
246: if (s != null) {
247: properties = new HashSet(1);
248: properties.add(s);
249: }
250: }
251: } catch (Exception e) {
252: // property might not exist - ignore.
253: }
254:
255: return (properties);
256: }
257: }
|