View Javadoc
1   /**
2    *    Copyright 2006-2016 the original author or authors.
3    *
4    *    Licensed under the Apache License, Version 2.0 (the "License");
5    *    you may not use this file except in compliance with the License.
6    *    You may obtain a copy of the License at
7    *
8    *       http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *    Unless required by applicable law or agreed to in writing, software
11   *    distributed under the License is distributed on an "AS IS" BASIS,
12   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *    See the License for the specific language governing permissions and
14   *    limitations under the License.
15   */
16  /*
17   *  Licensed under the Apache License, Version 2.0 (the "License");
18   *  you may not use this file except in compliance with the License.
19   *  You may obtain a copy of the License at
20   *
21   *      http://www.apache.org/licenses/LICENSE-2.0
22   *
23   *  Unless required by applicable law or agreed to in writing, software
24   *  distributed under the License is distributed on an "AS IS" BASIS,
25   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26   *  See the License for the specific language governing permissions and
27   *  limitations under the License.
28   */
29  package org.mybatis.generator.config.xml;
30  
31  import static org.mybatis.generator.internal.util.StringUtility.isTrue;
32  import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;
33  import static org.mybatis.generator.internal.util.messages.Messages.getString;
34  
35  import java.io.IOException;
36  import java.io.InputStream;
37  import java.net.URL;
38  import java.util.Properties;
39  
40  import org.mybatis.generator.config.ColumnOverride;
41  import org.mybatis.generator.config.ColumnRenamingRule;
42  import org.mybatis.generator.config.CommentGeneratorConfiguration;
43  import org.mybatis.generator.config.Configuration;
44  import org.mybatis.generator.config.Context;
45  import org.mybatis.generator.config.GeneratedKey;
46  import org.mybatis.generator.config.IgnoredColumn;
47  import org.mybatis.generator.config.JDBCConnectionConfiguration;
48  import org.mybatis.generator.config.JavaClientGeneratorConfiguration;
49  import org.mybatis.generator.config.JavaModelGeneratorConfiguration;
50  import org.mybatis.generator.config.JavaTypeResolverConfiguration;
51  import org.mybatis.generator.config.ModelType;
52  import org.mybatis.generator.config.PluginConfiguration;
53  import org.mybatis.generator.config.PropertyHolder;
54  import org.mybatis.generator.config.SqlMapGeneratorConfiguration;
55  import org.mybatis.generator.config.TableConfiguration;
56  import org.mybatis.generator.exception.XMLParserException;
57  import org.mybatis.generator.internal.ObjectFactory;
58  import org.w3c.dom.Element;
59  import org.w3c.dom.NamedNodeMap;
60  import org.w3c.dom.Node;
61  import org.w3c.dom.NodeList;
62  
63  /**
64   * This class parses configuration files into the new Configuration API
65   * 
66   * @author Jeff Butler
67   */
68  public class MyBatisGeneratorConfigurationParser {
69      private Properties extraProperties;
70      private Properties configurationProperties;
71  
72      public MyBatisGeneratorConfigurationParser(Properties extraProperties) {
73          super();
74          if (extraProperties == null) {
75              this.extraProperties = new Properties();
76          } else {
77              this.extraProperties = extraProperties;
78          }
79          configurationProperties = new Properties();
80      }
81  
82      public Configuration parseConfiguration(Element rootNode)
83              throws XMLParserException {
84  
85          Configuration configuration = new Configuration();
86  
87          NodeList nodeList = rootNode.getChildNodes();
88          for (int i = 0; i < nodeList.getLength(); i++) {
89              Node childNode = nodeList.item(i);
90  
91              if (childNode.getNodeType() != Node.ELEMENT_NODE) {
92                  continue;
93              }
94  
95              if ("properties".equals(childNode.getNodeName())) { //$NON-NLS-1$
96                  parseProperties(configuration, childNode);
97              } else if ("classPathEntry".equals(childNode.getNodeName())) { //$NON-NLS-1$
98                  parseClassPathEntry(configuration, childNode);
99              } else if ("context".equals(childNode.getNodeName())) { //$NON-NLS-1$
100                 parseContext(configuration, childNode);
101             }
102         }
103 
104         return configuration;
105     }
106 
107     protected void parseProperties(Configuration configuration, Node node)
108             throws XMLParserException {
109         Properties attributes = parseAttributes(node);
110         String resource = attributes.getProperty("resource"); //$NON-NLS-1$
111         String url = attributes.getProperty("url"); //$NON-NLS-1$
112 
113         if (!stringHasValue(resource)
114                 && !stringHasValue(url)) {
115             throw new XMLParserException(getString("RuntimeError.14")); //$NON-NLS-1$
116         }
117 
118         if (stringHasValue(resource)
119                 && stringHasValue(url)) {
120             throw new XMLParserException(getString("RuntimeError.14")); //$NON-NLS-1$
121         }
122 
123         URL resourceUrl;
124 
125         try {
126             if (stringHasValue(resource)) {
127                 resourceUrl = ObjectFactory.getResource(resource);
128                 if (resourceUrl == null) {
129                     throw new XMLParserException(getString(
130                             "RuntimeError.15", resource)); //$NON-NLS-1$
131                 }
132             } else {
133                 resourceUrl = new URL(url);
134             }
135 
136             InputStream inputStream = resourceUrl.openConnection()
137                     .getInputStream();
138 
139             configurationProperties.load(inputStream);
140             inputStream.close();
141         } catch (IOException e) {
142             if (stringHasValue(resource)) {
143                 throw new XMLParserException(getString(
144                         "RuntimeError.16", resource)); //$NON-NLS-1$
145             } else {
146                 throw new XMLParserException(getString(
147                         "RuntimeError.17", url)); //$NON-NLS-1$
148             }
149         }
150     }
151 
152     private void parseContext(Configuration configuration, Node node) {
153 
154         Properties attributes = parseAttributes(node);
155         String defaultModelType = attributes.getProperty("defaultModelType"); //$NON-NLS-1$
156         String targetRuntime = attributes.getProperty("targetRuntime"); //$NON-NLS-1$
157         String introspectedColumnImpl = attributes
158                 .getProperty("introspectedColumnImpl"); //$NON-NLS-1$
159         String id = attributes.getProperty("id"); //$NON-NLS-1$
160 
161         ModelType mt = defaultModelType == null ? null : ModelType
162                 .getModelType(defaultModelType);
163 
164         Context context = new Context(mt);
165         context.setId(id);
166         if (stringHasValue(introspectedColumnImpl)) {
167             context.setIntrospectedColumnImpl(introspectedColumnImpl);
168         }
169         if (stringHasValue(targetRuntime)) {
170             context.setTargetRuntime(targetRuntime);
171         }
172 
173         configuration.addContext(context);
174 
175         NodeList nodeList = node.getChildNodes();
176         for (int i = 0; i < nodeList.getLength(); i++) {
177             Node childNode = nodeList.item(i);
178 
179             if (childNode.getNodeType() != Node.ELEMENT_NODE) {
180                 continue;
181             }
182 
183             if ("property".equals(childNode.getNodeName())) { //$NON-NLS-1$
184                 parseProperty(context, childNode);
185             } else if ("plugin".equals(childNode.getNodeName())) { //$NON-NLS-1$
186                 parsePlugin(context, childNode);
187             } else if ("commentGenerator".equals(childNode.getNodeName())) { //$NON-NLS-1$
188                 parseCommentGenerator(context, childNode);
189             } else if ("jdbcConnection".equals(childNode.getNodeName())) { //$NON-NLS-1$
190                 parseJdbcConnection(context, childNode);
191             } else if ("javaModelGenerator".equals(childNode.getNodeName())) { //$NON-NLS-1$
192                 parseJavaModelGenerator(context, childNode);
193             } else if ("javaTypeResolver".equals(childNode.getNodeName())) { //$NON-NLS-1$
194                 parseJavaTypeResolver(context, childNode);
195             } else if ("sqlMapGenerator".equals(childNode.getNodeName())) { //$NON-NLS-1$
196                 parseSqlMapGenerator(context, childNode);
197             } else if ("javaClientGenerator".equals(childNode.getNodeName())) { //$NON-NLS-1$
198                 parseJavaClientGenerator(context, childNode);
199             } else if ("table".equals(childNode.getNodeName())) { //$NON-NLS-1$
200                 parseTable(context, childNode);
201             }
202         }
203     }
204 
205     protected void parseSqlMapGenerator(Context context, Node node) {
206         SqlMapGeneratorConfiguration sqlMapGeneratorConfiguration = new SqlMapGeneratorConfiguration();
207 
208         context.setSqlMapGeneratorConfiguration(sqlMapGeneratorConfiguration);
209 
210         Properties attributes = parseAttributes(node);
211         String targetPackage = attributes.getProperty("targetPackage"); //$NON-NLS-1$
212         String targetProject = attributes.getProperty("targetProject"); //$NON-NLS-1$
213 
214         sqlMapGeneratorConfiguration.setTargetPackage(targetPackage);
215         sqlMapGeneratorConfiguration.setTargetProject(targetProject);
216 
217         NodeList nodeList = node.getChildNodes();
218         for (int i = 0; i < nodeList.getLength(); i++) {
219             Node childNode = nodeList.item(i);
220 
221             if (childNode.getNodeType() != Node.ELEMENT_NODE) {
222                 continue;
223             }
224 
225             if ("property".equals(childNode.getNodeName())) { //$NON-NLS-1$
226                 parseProperty(sqlMapGeneratorConfiguration, childNode);
227             }
228         }
229     }
230 
231     protected void parseTable(Context context, Node node) {
232         TableConfiguration tc = new TableConfiguration(context);
233         context.addTableConfiguration(tc);
234 
235         Properties attributes = parseAttributes(node);
236         String catalog = attributes.getProperty("catalog"); //$NON-NLS-1$
237         String schema = attributes.getProperty("schema"); //$NON-NLS-1$
238         String tableName = attributes.getProperty("tableName"); //$NON-NLS-1$
239         String domainObjectName = attributes.getProperty("domainObjectName"); //$NON-NLS-1$
240         String alias = attributes.getProperty("alias"); //$NON-NLS-1$
241         String enableInsert = attributes.getProperty("enableInsert"); //$NON-NLS-1$
242         String enableSelectByPrimaryKey = attributes
243                 .getProperty("enableSelectByPrimaryKey"); //$NON-NLS-1$
244         String enableSelectByExample = attributes
245                 .getProperty("enableSelectByExample"); //$NON-NLS-1$
246         String enableUpdateByPrimaryKey = attributes
247                 .getProperty("enableUpdateByPrimaryKey"); //$NON-NLS-1$
248         String enableDeleteByPrimaryKey = attributes
249                 .getProperty("enableDeleteByPrimaryKey"); //$NON-NLS-1$
250         String enableDeleteByExample = attributes
251                 .getProperty("enableDeleteByExample"); //$NON-NLS-1$
252         String enableCountByExample = attributes
253                 .getProperty("enableCountByExample"); //$NON-NLS-1$
254         String enableUpdateByExample = attributes
255                 .getProperty("enableUpdateByExample"); //$NON-NLS-1$
256         String selectByPrimaryKeyQueryId = attributes
257                 .getProperty("selectByPrimaryKeyQueryId"); //$NON-NLS-1$
258         String selectByExampleQueryId = attributes
259                 .getProperty("selectByExampleQueryId"); //$NON-NLS-1$
260         String modelType = attributes.getProperty("modelType"); //$NON-NLS-1$
261         String escapeWildcards = attributes.getProperty("escapeWildcards"); //$NON-NLS-1$
262         String delimitIdentifiers = attributes
263                 .getProperty("delimitIdentifiers"); //$NON-NLS-1$
264         String delimitAllColumns = attributes.getProperty("delimitAllColumns"); //$NON-NLS-1$
265 
266         if (stringHasValue(catalog)) {
267             tc.setCatalog(catalog);
268         }
269 
270         if (stringHasValue(schema)) {
271             tc.setSchema(schema);
272         }
273 
274         if (stringHasValue(tableName)) {
275             tc.setTableName(tableName);
276         }
277 
278         if (stringHasValue(domainObjectName)) {
279             tc.setDomainObjectName(domainObjectName);
280         }
281 
282         if (stringHasValue(alias)) {
283             tc.setAlias(alias);
284         }
285 
286         if (stringHasValue(enableInsert)) {
287             tc.setInsertStatementEnabled(isTrue(enableInsert));
288         }
289 
290         if (stringHasValue(enableSelectByPrimaryKey)) {
291             tc.setSelectByPrimaryKeyStatementEnabled(
292                     isTrue(enableSelectByPrimaryKey));
293         }
294 
295         if (stringHasValue(enableSelectByExample)) {
296             tc.setSelectByExampleStatementEnabled(
297                     isTrue(enableSelectByExample));
298         }
299 
300         if (stringHasValue(enableUpdateByPrimaryKey)) {
301             tc.setUpdateByPrimaryKeyStatementEnabled(
302                     isTrue(enableUpdateByPrimaryKey));
303         }
304 
305         if (stringHasValue(enableDeleteByPrimaryKey)) {
306             tc.setDeleteByPrimaryKeyStatementEnabled(
307                     isTrue(enableDeleteByPrimaryKey));
308         }
309 
310         if (stringHasValue(enableDeleteByExample)) {
311             tc.setDeleteByExampleStatementEnabled(
312                     isTrue(enableDeleteByExample));
313         }
314 
315         if (stringHasValue(enableCountByExample)) {
316             tc.setCountByExampleStatementEnabled(
317                     isTrue(enableCountByExample));
318         }
319 
320         if (stringHasValue(enableUpdateByExample)) {
321             tc.setUpdateByExampleStatementEnabled(
322                     isTrue(enableUpdateByExample));
323         }
324 
325         if (stringHasValue(selectByPrimaryKeyQueryId)) {
326             tc.setSelectByPrimaryKeyQueryId(selectByPrimaryKeyQueryId);
327         }
328 
329         if (stringHasValue(selectByExampleQueryId)) {
330             tc.setSelectByExampleQueryId(selectByExampleQueryId);
331         }
332 
333         if (stringHasValue(modelType)) {
334             tc.setConfiguredModelType(modelType);
335         }
336 
337         if (stringHasValue(escapeWildcards)) {
338             tc.setWildcardEscapingEnabled(isTrue(escapeWildcards));
339         }
340 
341         if (stringHasValue(delimitIdentifiers)) {
342             tc.setDelimitIdentifiers(isTrue(delimitIdentifiers));
343         }
344 
345         if (stringHasValue(delimitAllColumns)) {
346             tc.setAllColumnDelimitingEnabled(isTrue(delimitAllColumns));
347         }
348 
349         NodeList nodeList = node.getChildNodes();
350         for (int i = 0; i < nodeList.getLength(); i++) {
351             Node childNode = nodeList.item(i);
352 
353             if (childNode.getNodeType() != Node.ELEMENT_NODE) {
354                 continue;
355             }
356 
357             if ("property".equals(childNode.getNodeName())) { //$NON-NLS-1$
358                 parseProperty(tc, childNode);
359             } else if ("columnOverride".equals(childNode.getNodeName())) { //$NON-NLS-1$
360                 parseColumnOverride(tc, childNode);
361             } else if ("ignoreColumn".equals(childNode.getNodeName())) { //$NON-NLS-1$
362                 parseIgnoreColumn(tc, childNode);
363             } else if ("generatedKey".equals(childNode.getNodeName())) { //$NON-NLS-1$
364                 parseGeneratedKey(tc, childNode);
365             } else if ("columnRenamingRule".equals(childNode.getNodeName())) { //$NON-NLS-1$
366                 parseColumnRenamingRule(tc, childNode);
367             }
368         }
369     }
370 
371     private void parseColumnOverride(TableConfiguration tc, Node node) {
372         Properties attributes = parseAttributes(node);
373         String column = attributes.getProperty("column"); //$NON-NLS-1$
374         String property = attributes.getProperty("property"); //$NON-NLS-1$
375         String javaType = attributes.getProperty("javaType"); //$NON-NLS-1$
376         String jdbcType = attributes.getProperty("jdbcType"); //$NON-NLS-1$
377         String typeHandler = attributes.getProperty("typeHandler"); //$NON-NLS-1$
378         String delimitedColumnName = attributes
379                 .getProperty("delimitedColumnName"); //$NON-NLS-1$
380 
381         ColumnOverride co = new ColumnOverride(column);
382 
383         if (stringHasValue(property)) {
384             co.setJavaProperty(property);
385         }
386 
387         if (stringHasValue(javaType)) {
388             co.setJavaType(javaType);
389         }
390 
391         if (stringHasValue(jdbcType)) {
392             co.setJdbcType(jdbcType);
393         }
394 
395         if (stringHasValue(typeHandler)) {
396             co.setTypeHandler(typeHandler);
397         }
398 
399         if (stringHasValue(delimitedColumnName)) {
400             co.setColumnNameDelimited(isTrue(delimitedColumnName));
401         }
402 
403         NodeList nodeList = node.getChildNodes();
404         for (int i = 0; i < nodeList.getLength(); i++) {
405             Node childNode = nodeList.item(i);
406 
407             if (childNode.getNodeType() != Node.ELEMENT_NODE) {
408                 continue;
409             }
410 
411             if ("property".equals(childNode.getNodeName())) { //$NON-NLS-1$
412                 parseProperty(co, childNode);
413             }
414         }
415 
416         tc.addColumnOverride(co);
417     }
418 
419     private void parseGeneratedKey(TableConfiguration tc, Node node) {
420         Properties attributes = parseAttributes(node);
421 
422         String column = attributes.getProperty("column"); //$NON-NLS-1$
423         boolean identity = isTrue(attributes
424                 .getProperty("identity")); //$NON-NLS-1$
425         String sqlStatement = attributes.getProperty("sqlStatement"); //$NON-NLS-1$
426         String type = attributes.getProperty("type"); //$NON-NLS-1$
427 
428         GeneratedKey gk = new GeneratedKey(column, sqlStatement, identity, type);
429 
430         tc.setGeneratedKey(gk);
431     }
432 
433     private void parseIgnoreColumn(TableConfiguration tc, Node node) {
434         Properties attributes = parseAttributes(node);
435         String column = attributes.getProperty("column"); //$NON-NLS-1$
436         String delimitedColumnName = attributes
437                 .getProperty("delimitedColumnName"); //$NON-NLS-1$
438 
439         IgnoredColumn ic = new IgnoredColumn(column);
440 
441         if (stringHasValue(delimitedColumnName)) {
442             ic.setColumnNameDelimited(isTrue(delimitedColumnName));
443         }
444 
445         tc.addIgnoredColumn(ic);
446     }
447 
448     private void parseColumnRenamingRule(TableConfiguration tc, Node node) {
449         Properties attributes = parseAttributes(node);
450         String searchString = attributes.getProperty("searchString"); //$NON-NLS-1$
451         String replaceString = attributes.getProperty("replaceString"); //$NON-NLS-1$
452 
453         ColumnRenamingRule crr = new ColumnRenamingRule();
454 
455         crr.setSearchString(searchString);
456 
457         if (stringHasValue(replaceString)) {
458             crr.setReplaceString(replaceString);
459         }
460 
461         tc.setColumnRenamingRule(crr);
462     }
463 
464     protected void parseJavaTypeResolver(Context context, Node node) {
465         JavaTypeResolverConfiguration javaTypeResolverConfiguration = new JavaTypeResolverConfiguration();
466 
467         context.setJavaTypeResolverConfiguration(javaTypeResolverConfiguration);
468 
469         Properties attributes = parseAttributes(node);
470         String type = attributes.getProperty("type"); //$NON-NLS-1$
471 
472         if (stringHasValue(type)) {
473             javaTypeResolverConfiguration.setConfigurationType(type);
474         }
475 
476         NodeList nodeList = node.getChildNodes();
477         for (int i = 0; i < nodeList.getLength(); i++) {
478             Node childNode = nodeList.item(i);
479 
480             if (childNode.getNodeType() != Node.ELEMENT_NODE) {
481                 continue;
482             }
483 
484             if ("property".equals(childNode.getNodeName())) { //$NON-NLS-1$
485                 parseProperty(javaTypeResolverConfiguration, childNode);
486             }
487         }
488     }
489 
490     private void parsePlugin(Context context, Node node) {
491         PluginConfiguration pluginConfiguration = new PluginConfiguration();
492 
493         context.addPluginConfiguration(pluginConfiguration);
494 
495         Properties attributes = parseAttributes(node);
496         String type = attributes.getProperty("type"); //$NON-NLS-1$
497 
498         pluginConfiguration.setConfigurationType(type);
499 
500         NodeList nodeList = node.getChildNodes();
501         for (int i = 0; i < nodeList.getLength(); i++) {
502             Node childNode = nodeList.item(i);
503 
504             if (childNode.getNodeType() != Node.ELEMENT_NODE) {
505                 continue;
506             }
507 
508             if ("property".equals(childNode.getNodeName())) { //$NON-NLS-1$
509                 parseProperty(pluginConfiguration, childNode);
510             }
511         }
512     }
513 
514     protected void parseJavaModelGenerator(Context context, Node node) {
515         JavaModelGeneratorConfiguration javaModelGeneratorConfiguration = new JavaModelGeneratorConfiguration();
516 
517         context
518                 .setJavaModelGeneratorConfiguration(javaModelGeneratorConfiguration);
519 
520         Properties attributes = parseAttributes(node);
521         String targetPackage = attributes.getProperty("targetPackage"); //$NON-NLS-1$
522         String targetProject = attributes.getProperty("targetProject"); //$NON-NLS-1$
523 
524         javaModelGeneratorConfiguration.setTargetPackage(targetPackage);
525         javaModelGeneratorConfiguration.setTargetProject(targetProject);
526 
527         NodeList nodeList = node.getChildNodes();
528         for (int i = 0; i < nodeList.getLength(); i++) {
529             Node childNode = nodeList.item(i);
530 
531             if (childNode.getNodeType() != Node.ELEMENT_NODE) {
532                 continue;
533             }
534 
535             if ("property".equals(childNode.getNodeName())) { //$NON-NLS-1$
536                 parseProperty(javaModelGeneratorConfiguration, childNode);
537             }
538         }
539     }
540 
541     private void parseJavaClientGenerator(Context context, Node node) {
542         JavaClientGeneratorConfiguration javaClientGeneratorConfiguration = new JavaClientGeneratorConfiguration();
543 
544         context.setJavaClientGeneratorConfiguration(javaClientGeneratorConfiguration);
545 
546         Properties attributes = parseAttributes(node);
547         String type = attributes.getProperty("type"); //$NON-NLS-1$
548         String targetPackage = attributes.getProperty("targetPackage"); //$NON-NLS-1$
549         String targetProject = attributes.getProperty("targetProject"); //$NON-NLS-1$
550         String implementationPackage = attributes
551                 .getProperty("implementationPackage"); //$NON-NLS-1$
552 
553         javaClientGeneratorConfiguration.setConfigurationType(type);
554         javaClientGeneratorConfiguration.setTargetPackage(targetPackage);
555         javaClientGeneratorConfiguration.setTargetProject(targetProject);
556         javaClientGeneratorConfiguration
557                 .setImplementationPackage(implementationPackage);
558 
559         NodeList nodeList = node.getChildNodes();
560         for (int i = 0; i < nodeList.getLength(); i++) {
561             Node childNode = nodeList.item(i);
562 
563             if (childNode.getNodeType() != Node.ELEMENT_NODE) {
564                 continue;
565             }
566 
567             if ("property".equals(childNode.getNodeName())) { //$NON-NLS-1$
568                 parseProperty(javaClientGeneratorConfiguration, childNode);
569             }
570         }
571     }
572 
573     protected void parseJdbcConnection(Context context, Node node) {
574         JDBCConnectionConfiguration jdbcConnectionConfiguration = new JDBCConnectionConfiguration();
575 
576         context.setJdbcConnectionConfiguration(jdbcConnectionConfiguration);
577 
578         Properties attributes = parseAttributes(node);
579         String driverClass = attributes.getProperty("driverClass"); //$NON-NLS-1$
580         String connectionURL = attributes.getProperty("connectionURL"); //$NON-NLS-1$
581         String userId = attributes.getProperty("userId"); //$NON-NLS-1$
582         String password = attributes.getProperty("password"); //$NON-NLS-1$
583 
584         jdbcConnectionConfiguration.setDriverClass(driverClass);
585         jdbcConnectionConfiguration.setConnectionURL(connectionURL);
586 
587         if (stringHasValue(userId)) {
588             jdbcConnectionConfiguration.setUserId(userId);
589         }
590 
591         if (stringHasValue(password)) {
592             jdbcConnectionConfiguration.setPassword(password);
593         }
594 
595         NodeList nodeList = node.getChildNodes();
596         for (int i = 0; i < nodeList.getLength(); i++) {
597             Node childNode = nodeList.item(i);
598 
599             if (childNode.getNodeType() != Node.ELEMENT_NODE) {
600                 continue;
601             }
602 
603             if ("property".equals(childNode.getNodeName())) { //$NON-NLS-1$
604                 parseProperty(jdbcConnectionConfiguration, childNode);
605             }
606         }
607     }
608 
609     protected void parseClassPathEntry(Configuration configuration, Node node) {
610         Properties attributes = parseAttributes(node);
611 
612         configuration.addClasspathEntry(attributes.getProperty("location")); //$NON-NLS-1$
613     }
614 
615     protected void parseProperty(PropertyHolder propertyHolder, Node node) {
616         Properties attributes = parseAttributes(node);
617 
618         String name = attributes.getProperty("name"); //$NON-NLS-1$
619         String value = attributes.getProperty("value"); //$NON-NLS-1$
620 
621         propertyHolder.addProperty(name, value);
622     }
623 
624     protected Properties parseAttributes(Node node) {
625         Properties attributes = new Properties();
626         NamedNodeMap nnm = node.getAttributes();
627         for (int i = 0; i < nnm.getLength(); i++) {
628             Node attribute = nnm.item(i);
629             String value = parsePropertyTokens(attribute.getNodeValue());
630             attributes.put(attribute.getNodeName(), value);
631         }
632 
633         return attributes;
634     }
635 
636     private String parsePropertyTokens(String string) {
637         final String OPEN = "${"; //$NON-NLS-1$
638         final String CLOSE = "}"; //$NON-NLS-1$
639 
640         String newString = string;
641         if (newString != null) {
642             int start = newString.indexOf(OPEN);
643             int end = newString.indexOf(CLOSE);
644 
645             while (start > -1 && end > start) {
646                 String prepend = newString.substring(0, start);
647                 String append = newString.substring(end + CLOSE.length());
648                 String propName = newString.substring(start + OPEN.length(),
649                         end);
650                 String propValue = resolveProperty(propName);
651                 if (propValue != null) {
652                     newString = prepend + propValue + append;
653                 }
654 
655                 start = newString.indexOf(OPEN, end);
656                 end = newString.indexOf(CLOSE, end);
657             }
658         }
659 
660         return newString;
661     }
662 
663     protected void parseCommentGenerator(Context context, Node node) {
664         CommentGeneratorConfiguration commentGeneratorConfiguration = new CommentGeneratorConfiguration();
665 
666         context.setCommentGeneratorConfiguration(commentGeneratorConfiguration);
667 
668         Properties attributes = parseAttributes(node);
669         String type = attributes.getProperty("type"); //$NON-NLS-1$
670 
671         if (stringHasValue(type)) {
672             commentGeneratorConfiguration.setConfigurationType(type);
673         }
674 
675         NodeList nodeList = node.getChildNodes();
676         for (int i = 0; i < nodeList.getLength(); i++) {
677             Node childNode = nodeList.item(i);
678 
679             if (childNode.getNodeType() != Node.ELEMENT_NODE) {
680                 continue;
681             }
682 
683             if ("property".equals(childNode.getNodeName())) { //$NON-NLS-1$
684                 parseProperty(commentGeneratorConfiguration, childNode);
685             }
686         }
687     }
688     
689     /**
690      * This method resolve a property from one of the three sources: system properties,
691      * properties loaded from the <properties> configuration element, and
692      * "extra" properties that may be supplied by the Maven or Ant envireonments.
693      * 
694      * If there is a name collision, system properties take precedence, followed by
695      * configuration properties, followed by extra properties.
696      * 
697      * @param key
698      * @return the resolved property.  This method will return null if the property is
699      *   undefined in any of the sources.
700      */
701     private String resolveProperty(String key) {
702         String property = null;
703     	
704         property = System.getProperty(key);
705     	
706         if (property == null) {
707             property = configurationProperties.getProperty(key);
708         }
709     	
710         if (property == null) {
711             property = extraProperties.getProperty(key);
712         }
713     	
714         return property;
715     }
716 }