Source Code Cross Referenced for DescriptorBuilder.java in  » Web-Services » xins » org » xins » common » service » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Web Services » xins » org.xins.common.service 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $Id: DescriptorBuilder.java,v 1.28 2007/03/16 09:54:59 agoubard Exp $
003:         *
004:         * Copyright 2003-2007 Orange Nederland Breedband B.V.
005:         * See the COPYRIGHT file for redistribution and use restrictions.
006:         */
007:        package org.xins.common.service;
008:
009:        import java.io.ByteArrayInputStream;
010:        import java.io.IOException;
011:        import java.net.MalformedURLException;
012:        import java.util.StringTokenizer;
013:
014:        import org.xins.common.Log;
015:        import org.xins.common.MandatoryArgumentChecker;
016:        import org.xins.common.collections.InvalidPropertyValueException;
017:        import org.xins.common.collections.MissingRequiredPropertyException;
018:        import org.xins.common.collections.PropertyReader;
019:        import org.xins.common.collections.PropertyReaderUtils;
020:        import org.xins.logdoc.ExceptionUtils;
021:
022:        /**
023:         * Builder that can build a <code>Descriptor</code> object based on a set of
024:         * properties.
025:         *
026:         * <h3>Examples</h3>
027:         *
028:         * <p>The following example is the definition of a single back-end at
029:         * <code>http://somehost/</code>, identified by the property name
030:         * <code>"s1"</code>, the time-out is set to 20 seconds:
031:         *
032:         * <blockquote><code>s1=service, http://somehost/, 20000</code></blockquote>
033:         *
034:         * <p>The next example is the definition of 4 back-ends, of which one will be
035:         * chosen randomly. This setting is identified by the property name
036:         * <code>"capi.sso"</code>:
037:         *
038:         * <blockquote><code># The root definition "capi.sso"
039:         * <br>capi.sso=group, random, target1, target2, target3, target4
040:         * <br>
041:         * <br># Total time-out is 12.5 seconds, no connection time-out and no socket
042:         * <br># time-out
043:         * <br>capi.sso.target1=service, http://somehost/, 12500
044:         * <br>
045:         * <br># Total time-out is 12.5 seconds, connection time-out is 4 seconds and
046:         * <br># no socket time-out
047:         * <br>capi.sso.target2=service, http://othrhost/, 12500, 4000
048:         * <br>
049:         * <br># Total time-out is 12.5 seconds, connection time-out is 4 seconds,
050:         * <br># socket time-out is 2 seconds
051:         * <br>capi.sso.target3=service, http://othrhost:2001/, 12500, 4000, 2000
052:         * <br>
053:         * <br># Total time-out is not set, connection time-out is not set and socket
054:         * <br># time-out is 2 seconds
055:         * <br>capi.sso.target4=service, http://othrhost:2002/, 0, 0,
056:         * 2000</code></blockquote>
057:         *
058:         * <p>The last example defines 2 back-ends at a more preferred location and 1
059:         * at a less-preferred location. Normally one of the 2 back-ends at the
060:         * preferred location will be chosen randomly, but if none is available, then
061:         * the back-end at the less preferred location will be tried. The time-out for
062:         * all back-ends in 8 seconds. The name of the property is <code>"ldap"</code>:
063:         *
064:         * <blockquote><code>ldap=group, ordered, loc1, host2a
065:         * <br>ldap.loc1=group, random, host1a, host1b
066:         * <br>ldap.host1a=service, ldap://host1a/, 8000
067:         * <br>ldap.host1b=service, ldap://host1b/, 8000
068:         * <br>ldap.host2a=service, ldap://host2a/, 8000</code></blockquote>
069:         *
070:         * @version $Revision: 1.28 $ $Date: 2007/03/16 09:54:59 $
071:         * @author <a href="mailto:ernst@ernstdehaan.com">Ernst de Haan</a>
072:         *
073:         * @since XINS 1.0.0
074:         */
075:        public final class DescriptorBuilder {
076:
077:            /**
078:             * Delimiter between tokens within a property value. This is the comma
079:             * character <code>','</code>.
080:             */
081:            public static final char DELIMITER = ',';
082:
083:            /**
084:             * Delimiter between property lines. This is the carraige return
085:             * character <code>'\n'</code>.
086:             */
087:            public static final char LINE_DELIMITER = '\n';
088:
089:            /**
090:             * Delimiters between tokens within a property value.
091:             */
092:            private static final String DELIMITER_AS_STRING = String
093:                    .valueOf(DELIMITER);
094:
095:            /**
096:             * Name identifying an actual target descriptor.
097:             */
098:            public static final String TARGET_DESCRIPTOR_TYPE = "service";
099:
100:            /**
101:             * Name identifying a group of descriptors.
102:             */
103:            public static final String GROUP_DESCRIPTOR_TYPE = "group";
104:
105:            /**
106:             * Constructs a new <code>DescriptorBuilder</code>.
107:             */
108:            private DescriptorBuilder() {
109:                // empty
110:
111:                // NOTE: No tracing is performed, since this constructor is never used
112:            }
113:
114:            /**
115:             * Tokenizes the specified string. The {@link #DELIMITER_AS_STRING} will be
116:             * used as the token delimiter. Every token will be one element in the
117:             * returned {@link String} array.
118:             *
119:             * @param s
120:             *    the {@link String} to tokenize, cannot be <code>null</code>.
121:             *
122:             * @return
123:             *    the list of tokens as a {@link String} array, never
124:             *    <code>null</code>.
125:             */
126:            private static String[] tokenize(String s) {
127:
128:                // Create a StringTokenizer
129:                StringTokenizer tokenizer = new StringTokenizer(s,
130:                        DELIMITER_AS_STRING);
131:
132:                // Create a new array to store the tokens in
133:                int count = tokenizer.countTokens();
134:                String[] tokens = new String[count];
135:
136:                // Copy all tokens into the array
137:                for (int i = 0; i < count; i++) {
138:                    tokens[i] = tokenizer.nextToken().trim();
139:                }
140:
141:                return tokens;
142:            }
143:
144:            /**
145:             * Builds a <code>Descriptor</code> based on the specified set of
146:             * properties, for the specified service caller.
147:             *
148:             * @param caller
149:             *    the caller to create a {@link Descriptor} for, can be
150:             *    <code>null</code> if unknown.
151:             *
152:             * @param properties
153:             *    the properties to read from, cannot be <code>null</code>.
154:             *
155:             * @param propertyName
156:             *    the base for the property names, cannot be <code>null</code>.
157:             *
158:             * @return
159:             *    the {@link Descriptor} that was built, never <code>null</code>.
160:             *
161:             * @throws IllegalArgumentException
162:             *    if <code>properties == null || propertyName == null</code>.
163:             *
164:             * @throws MissingRequiredPropertyException
165:             *    if the property named <code>propertyName</code> cannot be found in
166:             *    <code>properties</code>, or if a referenced property cannot be found.
167:             *
168:             * @throws InvalidPropertyValueException
169:             *    if the property named <code>propertyName</code> is found in
170:             *    <code>properties</code>, but the format of this property or the
171:             *    format of a referenced property is invalid.
172:             *
173:             * @since XINS 1.2.0
174:             */
175:            public static Descriptor build(ServiceCaller caller,
176:                    PropertyReader properties, String propertyName)
177:                    throws IllegalArgumentException,
178:                    MissingRequiredPropertyException,
179:                    InvalidPropertyValueException {
180:
181:                // Check preconditions
182:                MandatoryArgumentChecker.check("properties", properties,
183:                        "propertyName", propertyName);
184:                return build(caller, properties, propertyName, null);
185:            }
186:
187:            /**
188:             * Builds a <code>Descriptor</code> based on the specified set of
189:             * properties.
190:             *
191:             * @param properties
192:             *    the properties to read from, cannot be <code>null</code>.
193:             *
194:             * @param propertyName
195:             *    the base for the property names, cannot be <code>null</code>.
196:             *
197:             * @return
198:             *    the {@link Descriptor} that was built, never <code>null</code>.
199:             *
200:             * @throws IllegalArgumentException
201:             *    if <code>properties == null || propertyName == null</code>.
202:             *
203:             * @throws MissingRequiredPropertyException
204:             *    if the property named <code>propertyName</code> cannot be found in
205:             *    <code>properties</code>, or if a referenced property cannot be found.
206:             *
207:             * @throws InvalidPropertyValueException
208:             *    if the property named <code>propertyName</code> is found in
209:             *    <code>properties</code>, but the format of this property or the
210:             *    format of a referenced property is invalid.
211:             */
212:            public static Descriptor build(PropertyReader properties,
213:                    String propertyName) throws IllegalArgumentException,
214:                    MissingRequiredPropertyException,
215:                    InvalidPropertyValueException {
216:
217:                // Check preconditions
218:                MandatoryArgumentChecker.check("properties", properties,
219:                        "propertyName", propertyName);
220:                return build((ServiceCaller) null, properties, propertyName);
221:            }
222:
223:            /**
224:             * Builds a <code>Descriptor</code> based on the specified value.
225:             *
226:             * @param descriptorValue
227:             *    the value of the descriptor, cannot be <code>null</code>.
228:             *    the value must have the same value as specified at the top, the lines
229:             *    should be separated with '\n' and the first line must start with
230:             *    the name of the property followed by the sign '='.
231:             *
232:             * @return
233:             *    the {@link Descriptor} that was built, never <code>null</code>.
234:             *
235:             * @throws IllegalArgumentException
236:             *    if <code>descriptorValue == null</code> or the property name cannot
237:             *    be found in the value.
238:             *
239:             * @throws MissingRequiredPropertyException
240:             *    if the property named <code>propertyName</code> cannot be found in
241:             *    <code>properties</code>, or if a referenced property cannot be found.
242:             *
243:             * @throws InvalidPropertyValueException
244:             *    if the property named <code>propertyName</code> is found in
245:             *    <code>properties</code>, but the format of this property or the
246:             *    format of a referenced property is invalid.
247:             */
248:            public static Descriptor build(String descriptorValue)
249:                    throws IllegalArgumentException,
250:                    MissingRequiredPropertyException,
251:                    InvalidPropertyValueException {
252:
253:                // Check preconditions
254:                MandatoryArgumentChecker.check("descriptorValue",
255:                        descriptorValue);
256:
257:                int equalsPos = descriptorValue.indexOf('=');
258:                int crPos = descriptorValue.indexOf(LINE_DELIMITER);
259:                if (equalsPos <= 0 || (crPos > 0 && equalsPos > crPos)) {
260:                    throw new IllegalArgumentException(
261:                            "No property name found in \"" + descriptorValue
262:                                    + "\".");
263:                }
264:                String propertyName = descriptorValue.substring(0, equalsPos);
265:
266:                final String ENCODING = "ISO-8859-1";
267:                try {
268:                    byte[] bytes = descriptorValue.getBytes(ENCODING);
269:                    ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
270:                    PropertyReader properties = PropertyReaderUtils
271:                            .createPropertyReader(bais);
272:                    bais.close();
273:                    return build((ServiceCaller) null, properties, propertyName);
274:                } catch (IOException ioe) {
275:                    throw new InvalidPropertyValueException(propertyName,
276:                            descriptorValue);
277:                }
278:            }
279:
280:            /**
281:             * Builds a <code>Descriptor</code> based on the specified set of
282:             * properties, specifying base property and reference.
283:             *
284:             * @param caller
285:             *    the service caller to build a descriptor for, or <code>null</code> if
286:             *    unknown.
287:             *
288:             * @param properties
289:             *    the properties to read from, should not be <code>null</code>.
290:             *
291:             * @param baseProperty
292:             *    the name of the base property, should not be <code>null</code>.
293:             *
294:             * @param reference
295:             *    the name of the reference, relative to the base property, can be
296:             *    <code>null</code>.
297:             *
298:             * @return
299:             *    the {@link Descriptor} that was built, never <code>null</code>.
300:             *
301:             * @throws NullPointerException
302:             *    if <code>properties == null</code>.
303:             *
304:             * @throws MissingRequiredPropertyException
305:             *    if a required property cannot be found.
306:             *
307:             * @throws InvalidPropertyValueException
308:             *    if the property named <code>propertyName</code> is found in
309:             *    <code>properties</code>, but the format of this property or the
310:             *    format of a referenced property is invalid.
311:             */
312:            private static Descriptor build(ServiceCaller caller,
313:                    PropertyReader properties, String baseProperty,
314:                    String reference) throws NullPointerException,
315:                    MissingRequiredPropertyException,
316:                    InvalidPropertyValueException {
317:
318:                // Determine the property name
319:                String propertyName = reference == null ? baseProperty
320:                        : baseProperty + '.' + reference;
321:
322:                // Get the value of the property
323:                String value = properties.get(propertyName);
324:                if (value == null) {
325:                    throw new MissingRequiredPropertyException(propertyName);
326:                }
327:
328:                // Tokenize the value
329:                String[] tokens = tokenize(value);
330:                int tokenCount = tokens.length;
331:                if (tokenCount < 3) {
332:                    throw new InvalidPropertyValueException(propertyName,
333:                            value, "Expected at least 3 tokens.");
334:                }
335:
336:                // Determine the type
337:                String descriptorType = tokens[0];
338:
339:                // Parse target descriptor
340:                if (TARGET_DESCRIPTOR_TYPE.equals(descriptorType)) {
341:                    if (tokenCount > 5) {
342:                        throw new InvalidPropertyValueException(propertyName,
343:                                value, "Expected URL and time-out.");
344:                    }
345:
346:                    // Determine URL
347:                    String url = tokens[1];
348:
349:                    // Determine the total time-out (mandatory)
350:                    int timeOut;
351:                    try {
352:                        timeOut = Integer.parseInt(tokens[2]);
353:                    } catch (NumberFormatException nfe) {
354:                        throw new InvalidPropertyValueException(propertyName,
355:                                value,
356:                                "Unable to parse total time-out as a 32-bit integer number.");
357:                    }
358:                    if (timeOut < 0) {
359:                        throw new InvalidPropertyValueException(propertyName,
360:                                value, "Total time-out is negative.");
361:                    }
362:
363:                    // Determine the connection time-out (optional)
364:                    int connectionTimeOut;
365:                    if (tokenCount > 3) {
366:                        try {
367:                            connectionTimeOut = Integer.parseInt(tokens[3]);
368:                        } catch (NumberFormatException nfe) {
369:                            throw new InvalidPropertyValueException(
370:                                    propertyName, value,
371:                                    "Unable to parse connection time-out as a 32-bit integer number.");
372:                        }
373:                        if (connectionTimeOut < 0) {
374:                            throw new InvalidPropertyValueException(
375:                                    propertyName, value,
376:                                    "Connection time-out is negative.");
377:                        }
378:                    } else {
379:                        connectionTimeOut = 0;
380:                    }
381:
382:                    // Determine the socket time-out (optional)
383:                    int socketTimeOut;
384:                    if (tokenCount > 4) {
385:                        try {
386:                            socketTimeOut = Integer.parseInt(tokens[4]);
387:                        } catch (NumberFormatException nfe) {
388:                            throw new InvalidPropertyValueException(
389:                                    propertyName, value,
390:                                    "Unable to parse socket time-out as a 32-bit integer number.");
391:                        }
392:                        if (socketTimeOut < 0) {
393:                            throw new InvalidPropertyValueException(
394:                                    propertyName, value,
395:                                    "Socket time-out is negative.");
396:                        }
397:                    } else {
398:                        socketTimeOut = 0;
399:                    }
400:
401:                    // Construct a TargetDescriptor instance
402:                    TargetDescriptor td;
403:                    try {
404:                        td = new TargetDescriptor(url, timeOut,
405:                                connectionTimeOut, socketTimeOut);
406:                    } catch (MalformedURLException exception) {
407:                        Log.log_1300(exception, url);
408:                        throw new InvalidPropertyValueException(propertyName,
409:                                value, "Malformed URL.");
410:                    }
411:
412:                    // Test the protocol
413:                    if (caller != null) {
414:                        try {
415:                            caller.testTargetDescriptor(td);
416:                        } catch (UnsupportedProtocolException cause) {
417:                            Log.log_1308(url);
418:                            InvalidPropertyValueException exception = new InvalidPropertyValueException(
419:                                    propertyName, value,
420:                                    "Unsupported protocol.");
421:                            ExceptionUtils.setCause(exception, cause);
422:                            throw exception;
423:                        }
424:                    }
425:
426:                    return td;
427:
428:                    // Parse group descriptor
429:                } else if (GROUP_DESCRIPTOR_TYPE.equals(descriptorType)) {
430:
431:                    GroupDescriptor.Type groupType = GroupDescriptor
432:                            .getType(tokens[1]);
433:                    if (groupType == null) {
434:                        throw new InvalidPropertyValueException(propertyName,
435:                                value, "Unrecognized group descriptor type \""
436:                                        + tokens[1] + "\".");
437:                    }
438:
439:                    int memberCount = tokenCount - 2;
440:                    if (memberCount < 2) {
441:                        throw new InvalidPropertyValueException(propertyName,
442:                                value, "Group descriptor member count is "
443:                                        + memberCount + ", while minimum is 2.");
444:                    }
445:                    Descriptor[] members = new Descriptor[memberCount];
446:                    for (int i = 0; i < memberCount; i++) {
447:                        members[i] = build(caller, properties, baseProperty,
448:                                tokens[i + 2]);
449:                    }
450:                    return new GroupDescriptor(groupType, members);
451:
452:                    // Unrecognized descriptor type
453:                } else {
454:                    throw new InvalidPropertyValueException(propertyName,
455:                            value, "Expected valid descriptor type: either \""
456:                                    + TARGET_DESCRIPTOR_TYPE + "\" or \""
457:                                    + GROUP_DESCRIPTOR_TYPE + "\".");
458:                }
459:            }
460:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.