Source Code Cross Referenced for ConfigurationKey.java in  » Forum » mvnforum-1.1 » net » myvietnam » mvncore » configuration » 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 » Forum » mvnforum 1.1 » net.myvietnam.mvncore.configuration 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package net.myvietnam.mvncore.configuration;
002:
003:        /* ====================================================================
004:         * The Apache Software License, Version 1.1
005:         *
006:         * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
007:         * reserved.
008:         *
009:         * Redistribution and use in source and binary forms, with or without
010:         * modification, are permitted provided that the following conditions
011:         * are met:
012:         *
013:         * 1. Redistributions of source code must retain the above copyright
014:         *    notice, this list of conditions and the following disclaimer.
015:         *
016:         * 2. Redistributions in binary form must reproduce the above copyright
017:         *    notice, this list of conditions and the following disclaimer in
018:         *    the documentation and/or other materials provided with the
019:         *    distribution.
020:         *
021:         * 3. The end-user documentation included with the redistribution, if
022:         *    any, must include the following acknowlegement:
023:         *       "This product includes software developed by the
024:         *        Apache Software Foundation (http://www.apache.org/)."
025:         *    Alternately, this acknowlegement may appear in the software itself,
026:         *    if and wherever such third-party acknowlegements normally appear.
027:         *
028:         * 4. The names "The Jakarta Project", "Commons", and "Apache Software
029:         *    Foundation" must not be used to endorse or promote products derived
030:         *    from this software without prior written permission. For written
031:         *    permission, please contact apache@apache.org.
032:         *
033:         * 5. Products derived from this software may not be called "Apache"
034:         *    nor may "Apache" appear in their names without prior written
035:         *    permission of the Apache Group.
036:         *
037:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
038:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
039:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
040:         * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
041:         * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
042:         * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
043:         * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
044:         * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
045:         * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
046:         * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
047:         * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
048:         * SUCH DAMAGE.
049:         * ====================================================================
050:         *
051:         * This software consists of voluntary contributions made by many
052:         * individuals on behalf of the Apache Software Foundation.  For more
053:         * information on the Apache Software Foundation, please see
054:         * <http://www.apache.org/>.
055:         */
056:
057:        import java.io.Serializable;
058:        import java.util.Iterator;
059:        import java.util.NoSuchElementException;
060:
061:        /**
062:         * <p>A simple class that supports creation of and iteration on complex
063:         * configuration keys.</p>
064:         * <p>For key creation the class works similar to a StringBuffer: There are
065:         * several <code>appendXXXX()</code> methods with which single parts
066:         * of a key can be constructed. All these methods return a reference to the
067:         * actual object so they can be written in a chain. When using this methods
068:         * the exact syntax for keys need not be known.</p>
069:         * <p>This class also defines a specialized iterator for configuration keys.
070:         * With such an iterator a key can be tokenized into its single parts. For
071:         * each part it can be checked whether it has an associated index.</p>
072:         *
073:         * @author <a href="mailto:oliver.heger@t-online.de">Oliver Heger</a>
074:         * @version $Id: ConfigurationKey.java,v 1.2 2004/10/10 16:51:13 minhnn Exp $
075:         */
076:        public class ConfigurationKey implements  Serializable {
077:            /** Constant for an attribute start marker.*/
078:            private static final String ATTRIBUTE_START = "[@";
079:
080:            /** Constant for an attribute end marker.*/
081:            private static final String ATTRIBUTE_END = "]";
082:
083:            /** Constant for a property delimiter.*/
084:            private static final char PROPERTY_DELIMITER = '.';
085:
086:            /** Constant for an index start marker.*/
087:            private static final char INDEX_START = '(';
088:
089:            /** Constant for an index end marker.*/
090:            private static final char INDEX_END = ')';
091:
092:            /** Constant for the initial StringBuffer size.*/
093:            private static final int INITIAL_SIZE = 32;
094:
095:            /** Holds a buffer with the so far created key.*/
096:            private StringBuffer keyBuffer;
097:
098:            /**
099:             * Creates a new, empty instance of <code>ConfigurationKey</code>.
100:             */
101:            public ConfigurationKey() {
102:                keyBuffer = new StringBuffer(INITIAL_SIZE);
103:            }
104:
105:            /**
106:             * Creates a new instance of <code>ConfigurationKey</code> and
107:             * initializes it with the given key.
108:             * @param key the key as a string
109:             */
110:            public ConfigurationKey(String key) {
111:                keyBuffer = new StringBuffer(key);
112:                removeTrailingDelimiter();
113:            }
114:
115:            /**
116:             * Appends the name of a property to this key. If necessary, a
117:             * property delimiter will be added.
118:             * @param property the name of the property to be added
119:             * @return a reference to this object
120:             */
121:            public ConfigurationKey append(String property) {
122:                if (keyBuffer.length() > 0 && !hasDelimiter()
123:                        && !isAttributeKey(property)) {
124:                    keyBuffer.append(PROPERTY_DELIMITER);
125:                } /* if */
126:
127:                keyBuffer.append(property);
128:                removeTrailingDelimiter();
129:                return this ;
130:            }
131:
132:            /**
133:             * Appends an index to this configuration key.
134:             * @param index the index to be appended
135:             * @return a reference to this object
136:             */
137:            public ConfigurationKey appendIndex(int index) {
138:                keyBuffer.append(INDEX_START).append(index);
139:                keyBuffer.append(INDEX_END);
140:                return this ;
141:            }
142:
143:            /**
144:             * Appends an attribute to this configuration key.
145:             * @param attr the name of the attribute to be appended
146:             * @return a reference to this object
147:             */
148:            public ConfigurationKey appendAttribute(String attr) {
149:                keyBuffer.append(constructAttributeKey(attr));
150:                return this ;
151:            }
152:
153:            /**
154:             * Checks if the passed in key is an attribute key. Such attribute keys
155:             * start and end with certain marker strings. In some cases they must be
156:             * treated slightly different.
157:             * @param key the key (part) to be checked
158:             * @return a flag if this key is an attribute key
159:             */
160:            public static boolean isAttributeKey(String key) {
161:                return key != null && key.startsWith(ATTRIBUTE_START)
162:                        && key.endsWith(ATTRIBUTE_END);
163:            }
164:
165:            /**
166:             * Decorates the given key so that it represents an attribute. Adds
167:             * special start and end markers.
168:             * @param key the key to be decorated
169:             * @return the decorated attribute key
170:             */
171:            public static String constructAttributeKey(String key) {
172:                StringBuffer buf = new StringBuffer();
173:                buf.append(ATTRIBUTE_START).append(key).append(ATTRIBUTE_END);
174:                return buf.toString();
175:            }
176:
177:            /**
178:             * Extracts the name of the attribute from the given attribute key.
179:             * This method removes the attribute markers - if any - from the
180:             * specified key.
181:             * @param key the attribute key
182:             * @return the name of the corresponding attribute
183:             */
184:            public static String attributeName(String key) {
185:                return (isAttributeKey(key)) ? removeAttributeMarkers(key)
186:                        : key;
187:            }
188:
189:            /**
190:             * Helper method for removing attribute markers from a key.
191:             * @param key the key
192:             * @return the key with removed attribute markers
193:             */
194:            private static String removeAttributeMarkers(String key) {
195:                return key.substring(ATTRIBUTE_START.length(), key.length()
196:                        - ATTRIBUTE_END.length());
197:            }
198:
199:            /**
200:             * Helper method that checks if the actual buffer ends with a property
201:             * delimiter.
202:             * @return a flag if there is a trailing delimiter
203:             */
204:            private boolean hasDelimiter() {
205:                return keyBuffer.length() > 0
206:                        && keyBuffer.charAt(keyBuffer.length() - 1) == PROPERTY_DELIMITER;
207:            }
208:
209:            /**
210:             * Removes a trailing delimiter if there is any.
211:             */
212:            private void removeTrailingDelimiter() {
213:                while (hasDelimiter()) {
214:                    keyBuffer.deleteCharAt(keyBuffer.length() - 1);
215:                } /* while */
216:            }
217:
218:            /**
219:             * Returns a string representation of this object. This is the
220:             * configuration key as a plain string.
221:             * @return a string for this object
222:             */
223:            public String toString() {
224:                return keyBuffer.toString();
225:            }
226:
227:            /**
228:             * Returns an iterator for iterating over the single components of
229:             * this configuration key.
230:             * @return an iterator for this key
231:             */
232:            public KeyIterator iterator() {
233:                return new KeyIterator();
234:            }
235:
236:            /**
237:             * Returns the actual length of this configuration key.
238:             * @return the length of this key
239:             */
240:            public int length() {
241:                return keyBuffer.length();
242:            }
243:
244:            /**
245:             * Sets the new length of this configuration key. With this method it is
246:             * possible to truncate the key, e.g. to return to a state prior calling
247:             * some <code>append()</code> methods. The semantic is the same as
248:             * the <code>setLength()</code> method of <code>StringBuffer</code>.
249:             * @param len the new length of the key
250:             */
251:            public void setLength(int len) {
252:                keyBuffer.setLength(len);
253:            }
254:
255:            /**
256:             * Checks if two <code>ConfigurationKey</code> objects are equal. The
257:             * method can be called with strings or other objects, too.
258:             * @param c the object to compare
259:             * @return a flag if both objects are equal
260:             */
261:            public boolean equals(Object c) {
262:                if (c == null) {
263:                    return false;
264:                } /* if */
265:
266:                return keyBuffer.toString().equals(c.toString());
267:            }
268:
269:            /**
270:             * Returns the hash code for this object.
271:             * @return the hash code
272:             */
273:            public int hashCode() {
274:                return keyBuffer.hashCode();
275:            }
276:
277:            /**
278:             * Returns a configuration key object that is initialized with the part
279:             * of the key that is common to this key and the passed in key.
280:             * @param other the other key
281:             * @return a key object with the common key part
282:             */
283:            public ConfigurationKey commonKey(ConfigurationKey other) {
284:                if (other == null) {
285:                    throw new IllegalArgumentException(
286:                            "Other key must no be null!");
287:                } /* if */
288:
289:                ConfigurationKey result = new ConfigurationKey();
290:                KeyIterator it1 = iterator();
291:                KeyIterator it2 = other.iterator();
292:
293:                while (it1.hasNext() && it2.hasNext() && partsEqual(it1, it2)) {
294:                    if (it1.isAttribute()) {
295:                        result.appendAttribute(it1.currentKey());
296:                    } /* if */
297:                    else {
298:                        result.append(it1.currentKey());
299:                        if (it1.hasIndex) {
300:                            result.appendIndex(it1.getIndex());
301:                        } /* if */
302:                    } /* else */
303:                } /* while */
304:
305:                return result;
306:            }
307:
308:            /**
309:             * Returns the &quot;difference key&quot; to a given key. This value
310:             * is the part of the passed in key that differs from this key. There is
311:             * the following relation:
312:             * <code>other = key.commonKey(other) + key.differenceKey(other)</code>
313:             * for an arbitrary configuration key <code>key</code>.
314:             * @param other the key for which the difference is to be calculated
315:             * @return the difference key
316:             */
317:            public ConfigurationKey differenceKey(ConfigurationKey other) {
318:                ConfigurationKey common = commonKey(other);
319:                ConfigurationKey result = new ConfigurationKey();
320:
321:                if (common.length() < other.length()) {
322:                    String k = other.toString().substring(common.length());
323:                    // skip trailing delimiters
324:                    int i = 0;
325:                    while (i < k.length() && k.charAt(i) == PROPERTY_DELIMITER) {
326:                        i++;
327:                    } /* while */
328:
329:                    if (i < k.length()) {
330:                        result.append(k.substring(i));
331:                    } /* if */
332:                } /* if */
333:
334:                return result;
335:            }
336:
337:            /**
338:             * Helper method for comparing two key parts.
339:             * @param it1 the iterator with the first part
340:             * @param it2 the iterator with the second part
341:             * @return a flag if both parts are equal
342:             */
343:            private static boolean partsEqual(KeyIterator it1, KeyIterator it2) {
344:                return it1.nextKey().equals(it2.nextKey())
345:                        && it1.getIndex() == it2.getIndex()
346:                        && it1.isAttribute() == it2.isAttribute();
347:            }
348:
349:            /**
350:             * A specialized iterator class for tokenizing a configuration key.
351:             * This class implements the normal iterator interface. In addition it
352:             * provides some specific methods for configuration keys.
353:             *
354:             * @author <a href="mailto:oliver.heger@t-online.de">Oliver Heger</a>
355:             */
356:            public class KeyIterator implements  Iterator, Cloneable {
357:                /** Stores the current key name.*/
358:                private String current;
359:
360:                /** Stores the start index of the actual token.*/
361:                private int startIndex;
362:
363:                /** Stores the end index of the actual token.*/
364:                private int endIndex;
365:
366:                /** Stores the index of the actual property if there is one.*/
367:                private int indexValue;
368:
369:                /** Stores a flag if the actual property has an index.*/
370:                private boolean hasIndex;
371:
372:                /** Stores a flag if the actual property is an attribute.*/
373:                private boolean attribute;
374:
375:                /**
376:                 * Helper method for determining the next indices.
377:                 */
378:                private void findNextIndices() {
379:                    startIndex = endIndex;
380:                    // skip empty names
381:                    while (startIndex < keyBuffer.length()
382:                            && keyBuffer.charAt(startIndex) == PROPERTY_DELIMITER) {
383:                        startIndex++;
384:                    }
385:
386:                    // Key ends with a delimiter?
387:                    if (startIndex >= keyBuffer.length()) {
388:                        endIndex = keyBuffer.length();
389:                        startIndex = endIndex - 1;
390:                    } else {
391:                        String s = keyBuffer.toString(); // for compatibility
392:                        endIndex = s.indexOf(PROPERTY_DELIMITER, startIndex);
393:                        if (endIndex < 0) {
394:                            endIndex = s.indexOf(ATTRIBUTE_START, startIndex);
395:                            if (endIndex < 0 || endIndex == startIndex) {
396:                                endIndex = keyBuffer.length();
397:                            }
398:                        }
399:                    }
400:                }
401:
402:                /**
403:                 * Returns the next key part of this configuration key. This is a short
404:                 * form of <code>nextKey(false)</code>.
405:                 * @return the next key part
406:                 */
407:                public String nextKey() {
408:                    return nextKey(false);
409:                }
410:
411:                /**
412:                 * Returns the next key part of this configuration key. The boolean
413:                 * parameter indicates wheter a decorated key should be returned. This
414:                 * affects only attribute keys: if the parameter is <b>false</b>, the
415:                 * attribute markers are stripped from the key; if it is <b>true</b>,
416:                 * they remain.
417:                 * @param decorated a flag if the decorated key is to be returned
418:                 * @return the next key part
419:                 */
420:                public String nextKey(boolean decorated) {
421:                    if (!hasNext()) {
422:                        throw new NoSuchElementException("No more key parts!");
423:                    } /* if */
424:
425:                    hasIndex = false;
426:                    indexValue = -1;
427:                    findNextIndices();
428:                    String key = keyBuffer.substring(startIndex, endIndex)
429:                            .toString();
430:
431:                    attribute = checkAttribute(key);
432:                    if (!attribute) {
433:                        hasIndex = checkIndex(key);
434:                        if (!hasIndex) {
435:                            current = key;
436:                        } /* if */
437:                    } /* if */
438:
439:                    return currentKey(decorated);
440:                }
441:
442:                /**
443:                 * Helper method for checking if the passed key is an attribute.
444:                 * If this is the case, the internal fields will be set.
445:                 * @param key the key to be checked
446:                 * @return a flag if the key is an attribute
447:                 */
448:                private boolean checkAttribute(String key) {
449:                    if (isAttributeKey(key)) {
450:                        current = removeAttributeMarkers(key);
451:                        return true;
452:                    } /* if */
453:                    else {
454:                        return false;
455:                    } /* else */
456:                }
457:
458:                /**
459:                 * Helper method for checking if the passed key contains an index.
460:                 * If this is the case, internal fields will be set.
461:                 * @param key the key to be checked
462:                 * @return a flag if an index is defined
463:                 */
464:                private boolean checkIndex(String key) {
465:                    boolean result = false;
466:
467:                    int idx = key.indexOf(INDEX_START);
468:                    if (idx > 0) {
469:                        int endidx = key.indexOf(INDEX_END, idx);
470:
471:                        if (endidx > idx + 1) {
472:                            indexValue = Integer.parseInt(key.substring(
473:                                    idx + 1, endidx));
474:                            current = key.substring(0, idx);
475:                            result = true;
476:                        } /* if */
477:                    } /* if */
478:
479:                    return result;
480:                }
481:
482:                /**
483:                 * Checks if there is a next element.
484:                 * @return a flag if there is a next element
485:                 */
486:                public boolean hasNext() {
487:                    return endIndex < keyBuffer.length();
488:                }
489:
490:                /**
491:                 * Returns the next object in the iteration.
492:                 * @return the next object
493:                 */
494:                public Object next() {
495:                    return nextKey();
496:                }
497:
498:                /**
499:                 * Removes the current object in the iteration. This method is not
500:                 * supported by this iterator type, so an exception is thrown.
501:                 */
502:                public void remove() {
503:                    throw new UnsupportedOperationException(
504:                            "Remove not supported!");
505:                }
506:
507:                /**
508:                 * Returns the current key of the iteration (without skipping to the
509:                 * next element). This is the same key the previous <code>next()</code>
510:                 * call had returned. (Short form of <code>currentKey(false)</code>.
511:                 * @return the current key
512:                 */
513:                public String currentKey() {
514:                    return currentKey(false);
515:                }
516:
517:                /**
518:                 * Returns the current key of the iteration (without skipping to the
519:                 * next element). The boolean parameter indicates wheter a decorated
520:                 * key should be returned. This affects only attribute keys: if the
521:                 * parameter is <b>false</b>, the attribute markers are stripped from
522:                 * the key; if it is <b>true</b>, they remain.
523:                 * @param decorated a flag if the decorated key is to be returned
524:                 * @return the current key
525:                 */
526:                public String currentKey(boolean decorated) {
527:                    return (decorated && isAttribute()) ? constructAttributeKey(current)
528:                            : current;
529:                }
530:
531:                /**
532:                 * Returns a flag if the current key is an attribute. This method can
533:                 * be called after <code>next()</code>.
534:                 * @return a flag if the current key is an attribute
535:                 */
536:                public boolean isAttribute() {
537:                    return attribute;
538:                }
539:
540:                /**
541:                 * Returns the index value of the current key. If the current key does
542:                 * not have an index, return value is -1. This method can be called
543:                 * after <code>next()</code>.
544:                 * @return the index value of the current key
545:                 */
546:                public int getIndex() {
547:                    return indexValue;
548:                }
549:
550:                /**
551:                 * Returns a flag if the current key has an associated index.
552:                 * This method can be called after <code>next()</code>.
553:                 * @return a flag if the current key has an index
554:                 */
555:                public boolean hasIndex() {
556:                    return hasIndex;
557:                }
558:
559:                /**
560:                 * Creates a clone of this object.
561:                 * @return a clone of this object
562:                 */
563:                protected Object clone() {
564:                    try {
565:                        return super .clone();
566:                    } /* try */
567:                    catch (CloneNotSupportedException cex) {
568:                        // should not happen
569:                        return null;
570:                    } /* catch */
571:                }
572:
573:            }
574:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.