Source Code Cross Referenced for ConfigLoader.java in  » Database-ORM » Velosurf » velosurf » sql » 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 » Database ORM » Velosurf » velosurf.sql 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2003 The Apache Software Foundation.
0003:         *
0004:         * Licensed under the Apache License, Version 2.0 (the "License");
0005:         * you may not use this file except in compliance with the License.
0006:         * You may obtain a copy of the License at
0007:         *
0008:         *     http://www.apache.org/licenses/LICENSE-2.0
0009:         *
0010:         * Unless required by applicable law or agreed to in writing, software
0011:         * distributed under the License is distributed on an "AS IS" BASIS,
0012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013:         * See the License for the specific language governing permissions and
0014:         * limitations under the License.
0015:         */
0016:
0017:        package velosurf.sql;
0018:
0019:        import java.util.Iterator;
0020:        import java.util.List;
0021:        import java.util.ArrayList;
0022:        import java.util.StringTokenizer;
0023:        import java.util.Arrays;
0024:        import java.util.Date;
0025:        import java.util.regex.Pattern;
0026:        import java.io.InputStream;
0027:        import java.sql.SQLException;
0028:        import java.text.DateFormat;
0029:        import java.text.SimpleDateFormat;
0030:
0031:        import org.jdom.Document;
0032:        import org.jdom.Element;
0033:        import org.jdom.Text;
0034:        import org.jdom.input.SAXBuilder;
0035:
0036:        import velosurf.util.Logger;
0037:        import velosurf.util.StringLists;
0038:        import velosurf.util.Strings;
0039:        import velosurf.util.XIncludeResolver;
0040:        import velosurf.cache.Cache;
0041:        import velosurf.model.Entity;
0042:        import velosurf.model.Action;
0043:        import velosurf.model.Attribute;
0044:        import velosurf.model.Transaction;
0045:        import velosurf.model.ImportedKey;
0046:        import velosurf.model.ExportedKey;
0047:        import velosurf.validation.Email;
0048:        import velosurf.validation.Length;
0049:        import velosurf.validation.Range;
0050:        import velosurf.validation.NotNull;
0051:        import velosurf.validation.OneOf;
0052:        import velosurf.validation.Reference;
0053:        import velosurf.validation.Regex;
0054:        import velosurf.validation.FieldConstraint;
0055:        import velosurf.validation.DateRange;
0056:        import velosurf.validation.NotEmpty;
0057:
0058:        /** A configuration loader for the Database object.
0059:         *
0060:         *  @author <a href="mailto:claude.brisson@gmail.com">Claude Brisson</a>
0061:         */
0062:
0063:        public class ConfigLoader {
0064:
0065:            /** Database. */
0066:            private Database database = null;
0067:            /** &lt;<code>xi:include</code>&gt; tag resolver. */
0068:            private XIncludeResolver xincludeResolver = null;
0069:            /** Syntax checker pattern for the <code>result</code> attribute of &lt;<code>attribute</code>&gt; tags. */
0070:            private static final Pattern attributeResultSyntax = Pattern
0071:                    .compile("^scalar|(?:(?:row|rowset)(?:/.+)?)$");
0072:
0073:            /**
0074:             * Constructor.
0075:             * @param db database
0076:             */
0077:            public ConfigLoader(Database db) {
0078:                this (db, null);
0079:            }
0080:
0081:            /**
0082:             * Constructor.
0083:             * @param db database
0084:             * @param xincludeResolver &lt;<code>xi:include</code>&gt; tag resolver
0085:             */
0086:            public ConfigLoader(Database db, XIncludeResolver xincludeResolver) {
0087:                database = db;
0088:                this .xincludeResolver = xincludeResolver;
0089:            }
0090:
0091:            /**
0092:             * Main method of the ConfigLoader.
0093:             * @param config the configuration input stream
0094:             * @throws Exception
0095:             */
0096:            public void loadConfig(InputStream config) throws Exception {
0097:
0098:                Logger.info("reading properties...");
0099:
0100:                /* build JDOM tree */
0101:                Document document = new SAXBuilder().build(config);
0102:                if (xincludeResolver != null) {
0103:                    document = xincludeResolver.resolve(document);
0104:                }
0105:                Element database = document.getRootElement();
0106:
0107:                setDatabaseAttributes(database);
0108:
0109:                /* define root attributes */
0110:                defineAttributes(database, this .database.getRootEntity());
0111:
0112:                /* define root actions */
0113:                defineActions(database, this .database.getRootEntity());
0114:
0115:                /* define entities */
0116:                defineEntities(database);
0117:
0118:                Logger.info("Config file successfully read.");
0119:            }
0120:
0121:            /**
0122:             * Adapt the case to match chosen database case policy.
0123:             * @param str string to adapt
0124:             * @return adapted string
0125:             */
0126:            private String adaptCase(String str) {
0127:                return database.adaptCase(str);
0128:            }
0129:
0130:            /**
0131:             * Parses database XML attributes.
0132:             * @param database parent element
0133:             */
0134:            private void setDatabaseAttributes(Element database) {
0135:
0136:                /* log level */
0137:                String loglevel = database.getAttributeValue("loglevel");
0138:                if (checkSyntax("loglevel", loglevel, new String[] { "trace",
0139:                        "debug", "info", "warn", "error", "fatal" })) {
0140:                    if ("trace".equalsIgnoreCase(loglevel))
0141:                        Logger.setLogLevel(Logger.TRACE_ID);
0142:                    else if ("debug".equalsIgnoreCase(loglevel))
0143:                        Logger.setLogLevel(Logger.DEBUG_ID);
0144:                    else if ("info".equalsIgnoreCase(loglevel))
0145:                        Logger.setLogLevel(Logger.INFO_ID);
0146:                    else if ("warn".equalsIgnoreCase(loglevel))
0147:                        Logger.setLogLevel(Logger.WARN_ID);
0148:                    else if ("error".equalsIgnoreCase(loglevel))
0149:                        Logger.setLogLevel(Logger.ERROR_ID);
0150:                    else if ("fatal".equalsIgnoreCase(loglevel))
0151:                        Logger.setLogLevel(Logger.FATAL_ID);
0152:                    else
0153:                        Logger
0154:                                .error("Invalid loglevel. Should be one of: trace, debug, info, warn, error, fatal.");
0155:                }
0156:
0157:                /* default-access - deprecated - for compatibility only, replaced with read-only=true|false */
0158:                String access = database.getAttributeValue("default-access");
0159:                if (access != null) {
0160:                    Logger
0161:                            .warn("The syntax <database default-access=\"rw|ro\"> is deprecated.");
0162:                    Logger
0163:                            .warn("Please use <database read-only=\"true|false\"> instead.");
0164:                    if (checkSyntax("access", access,
0165:                            new String[] { "ro", "rw" })) {
0166:                        this .database.setReadOnly(!access
0167:                                .equalsIgnoreCase("rw"));
0168:                    }
0169:                }
0170:
0171:                /* read-only */
0172:                String ro = database.getAttributeValue("read-only");
0173:                if (ro != null) {
0174:                    /* check syntax but continue anyway with read-only database if the syntax is bad */
0175:                    checkSyntax("read-only", ro, new String[] { "true",
0176:                            "false", "yes", "no" });
0177:                    /* default to true - using Boolean.parseBoolean is not possible */
0178:                    this .database.setReadOnly(!ro.equalsIgnoreCase("false")
0179:                            && !ro.equalsIgnoreCase("no"));
0180:                }
0181:
0182:                String caching = database.getAttributeValue("default-caching");
0183:                if (caching != null) {
0184:                    Logger
0185:                            .warn("attribute 'default-caching' is deprecatd, please use 'caching' instead.");
0186:                } else {
0187:                    caching = database.getAttributeValue("caching");
0188:                }
0189:                if (checkSyntax("caching", caching, new String[] { "none",
0190:                        "no", "yes", "soft", "full" })) {
0191:                    int val = parseCaching(caching);
0192:                    this .database.setCaching(val);
0193:                    if (val == Cache.FULL_CACHE)
0194:                        Logger
0195:                                .warn("The 'full' caching method is deprecated and will be removed in future versions.");
0196:                }
0197:
0198:                String reverseMode = database.getAttributeValue("reverse");
0199:                if (checkSyntax("reverse", reverseMode, new String[] { "none",
0200:                        "partial", "tables", "full" })) {
0201:                    int mode = -1;
0202:                    if ("full".equalsIgnoreCase(reverseMode)
0203:                            || reverseMode == null) {
0204:                        mode = ReverseEngineer.REVERSE_FULL;
0205:                    } else if ("partial".equalsIgnoreCase(reverseMode)) {
0206:                        mode = ReverseEngineer.REVERSE_PARTIAL;
0207:                    } else if ("tables".equalsIgnoreCase(reverseMode)) {
0208:                        mode = ReverseEngineer.REVERSE_TABLES;
0209:                    } else if ("none".equalsIgnoreCase(reverseMode)) {
0210:                        mode = ReverseEngineer.REVERSE_NONE;
0211:                    }
0212:                    this .database.getReverseEngineer().setReverseMode(mode);
0213:                }
0214:
0215:                Element credentials = database.getChild("credentials");
0216:                if (credentials == null) {
0217:                    credentials = database;
0218:                }
0219:
0220:                this .database.setUser(credentials.getAttributeValue("user"));
0221:                this .database.setPassword(credentials
0222:                        .getAttributeValue("password"));
0223:
0224:                String url = credentials.getAttributeValue("url");
0225:                if (url == null) {
0226:                    url = database.getAttributeValue("url");
0227:                }
0228:                this .database.setURL(url);
0229:
0230:                String driver = credentials.getAttributeValue("driver");
0231:                if (driver == null) {
0232:                    driver = database.getAttributeValue("driver");
0233:                }
0234:                this .database.setDriver(driver);
0235:
0236:                String schema = adaptCase(credentials
0237:                        .getAttributeValue("schema"));
0238:                if (schema == null) {
0239:                    schema = adaptCase(database.getAttributeValue("schema"));
0240:                }
0241:                if (schema != null) {
0242:                    this .database.setSchema(schema);
0243:                }
0244:
0245:                /* load driver now so as to know default behaviours */
0246:                this .database.loadDriver();
0247:
0248:                int min = 0;
0249:                String minstr = database.getAttributeValue("min-connections");
0250:                if (minstr != null) {
0251:                    try {
0252:                        min = Integer.parseInt(minstr);
0253:                        if (min > 0)
0254:                            this .database.setMinConnections(min);
0255:                        else
0256:                            Logger
0257:                                    .error("the parameter 'min-connections' wants an integer > 0 !");
0258:                    } catch (NumberFormatException nfe) {
0259:                        Logger
0260:                                .error("the parameter 'min-connections' wants an integer!");
0261:                    }
0262:                }
0263:
0264:                String maxstr = database.getAttributeValue("max-connections");
0265:                if (maxstr != null) {
0266:                    try {
0267:                        int max = Integer.parseInt(maxstr);
0268:                        if (max >= min)
0269:                            this .database.setMaxConnections(max);
0270:                        else
0271:                            Logger
0272:                                    .error("the parameter 'max-connections' must be >= min-connection!");
0273:                    } catch (NumberFormatException nfe) {
0274:                        Logger
0275:                                .error("the parameter 'max-connections' wants an integer!");
0276:                    }
0277:                }
0278:
0279:                this .database.setSeed(database.getAttributeValue("seed"));
0280:
0281:                String caseSensivity = database.getAttributeValue("case");
0282:                /* if case-sensivity has not been set explicitely, deduce it from the driver */
0283:                if (caseSensivity == null) {
0284:                    caseSensivity = this .database.getDriverInfo()
0285:                            .getCaseSensivity();
0286:                }
0287:                if (checkSyntax("case", caseSensivity, new String[] {
0288:                        "sensitive", "uppercase", "lowercase" })) {
0289:                    Logger.info("Case sensivity: " + caseSensivity);
0290:                    if ("sensitive".equalsIgnoreCase(caseSensivity)) {
0291:                        this .database.setCase(Database.CASE_SENSITIVE);
0292:                    } else if ("uppercase".equalsIgnoreCase(caseSensivity)) {
0293:                        this .database.setCase(Database.UPPERCASE);
0294:                    } else if ("lowercase".equalsIgnoreCase(caseSensivity)) {
0295:                        this .database.setCase(Database.LOWERCASE);
0296:                    }
0297:                }
0298:
0299:                /* root database entity (never read-only koz not a real entity and we must allow external parameters */
0300:                Entity root = new Entity(this .database, "velosurf.root", false,
0301:                        Cache.NO_CACHE);
0302:                this .database.addEntity(root);
0303:            }
0304:
0305:            /**
0306:             * Define Velosurf attributes.
0307:             * @param parent parent XML element
0308:             * @param entity parent entity
0309:             * @throws SQLException
0310:             */
0311:            @SuppressWarnings("deprecation")
0312:            private void defineAttributes(Element parent, Entity entity)
0313:                    throws SQLException {
0314:                for (Iterator attributes = parent.getChildren("attribute")
0315:                        .iterator(); attributes.hasNext();) {
0316:                    Element element = (Element) attributes.next();
0317:                    String name = adaptCase(element.getAttributeValue("name"));
0318:                    Attribute attribute = new Attribute(name, entity);
0319:                    String result = element.getAttributeValue("result");
0320:                    if (result == null) {
0321:                        Logger
0322:                                .warn("Attribute '"
0323:                                        + name
0324:                                        + "' doesn't have a 'result' attribute... using rowset as default.");
0325:                        result = "rowset";
0326:                    }
0327:                    if (attributeResultSyntax.matcher(result).matches()) {
0328:                        int type = 0;
0329:                        if (result.equals("scalar")) {
0330:                            type = Attribute.SCALAR;
0331:                        } else if (result.startsWith("rowset")) {
0332:                            type = Attribute.ROWSET;
0333:                        } else if (result.startsWith("row")) {
0334:                            type = Attribute.ROW;
0335:                        } else {
0336:                            throw new SQLException(
0337:                                    "bad syntax for the 'result' attribute: "
0338:                                            + result);
0339:                        }
0340:                        attribute.setResultType(type);
0341:                        int slash = result.indexOf("/");
0342:                        if (slash > -1 && slash + 1 < result.length()) {
0343:                            attribute.setResultEntity(adaptCase(result
0344:                                    .substring(slash + 1)));
0345:                        }
0346:                    }
0347:
0348:                    String foreignKey = element
0349:                            .getAttributeValue("foreign-key");
0350:                    if (foreignKey != null) {
0351:                        Logger
0352:                                .warn("use of the foreign-key attribute for the <attribute> tag is deprecated. Please use <imported-key>");
0353:                        if (attribute.getResultEntity() == null) {
0354:                            throw new SQLException(
0355:                                    "Attribute '"
0356:                                            + name
0357:                                            + "' is a foreign key, Velosurf needs to know its result entity!");
0358:                        }
0359:                        attribute.setForeignKeyColumn(foreignKey);
0360:                    }
0361:
0362:                    /* attribute parameters and query */
0363:                    if (foreignKey != null) {
0364:                        attribute.addParamName(adaptCase(foreignKey));
0365:                    } else {
0366:                        String query = "";
0367:                        Iterator queryElements = element.getContent()
0368:                                .iterator();
0369:                        while (queryElements.hasNext()) {
0370:                            Object content = queryElements.next();
0371:                            if (content instanceof  Text)
0372:                                query += Strings
0373:                                        .trimSpacesAndEOL(((Text) content)
0374:                                                .getText());
0375:                            else if (content instanceof  Element) {
0376:                                query += " ? ";
0377:                                Element elem = (Element) content;
0378:                                attribute
0379:                                        .addParamName(adaptCase(elem.getName()));
0380:                            } else {
0381:                                Logger
0382:                                        .error("Try upgrading your jdom library!");
0383:                                throw new SQLException(
0384:                                        "Was expecting an org.jdom.Element, found a "
0385:                                                + content.getClass().getName()
0386:                                                + ": '" + content + "'");
0387:                            }
0388:                        }
0389:                        /* trim */
0390:                        query = Pattern.compile(";\\s*\\Z").matcher(query)
0391:                                .replaceFirst("");
0392:                        attribute.setQuery(query);
0393:                    }
0394:
0395:                    /* caching */
0396:                    String caching = element.getAttributeValue("caching");
0397:                    if (checkSyntax("caching", caching, new String[] { "no",
0398:                            "yes" })) {
0399:                        attribute.setCaching(caching.equals("yes"));
0400:                    }
0401:
0402:                    entity.addAttribute(attribute);
0403:                }
0404:            }
0405:
0406:            /**
0407:             * Define foreign keys.
0408:             * @param parent parent XML element
0409:             * @param entity parent entity
0410:             */
0411:            private void defineForeignKeys(Element parent, Entity entity) {
0412:                for (Iterator imported = parent.getChildren("imported-key")
0413:                        .iterator(); imported.hasNext();) {
0414:                    Element keyelem = (Element) imported.next();
0415:                    String name = keyelem.getAttributeValue("name");
0416:                    if (name == null) {
0417:                        Logger
0418:                                .error("tag <imported-key> needs a 'name' attribute!");
0419:                        continue;
0420:                    }
0421:                    String pkEntity = keyelem.getAttributeValue("entity");
0422:                    if (pkEntity == null) {
0423:                        Logger
0424:                                .error("tag <imported-key> needs an 'entity' attribute (name='"
0425:                                        + name + "')!");
0426:                        continue;
0427:                    }
0428:                    List<String> fkCols = null;
0429:                    String foreignCols = keyelem
0430:                            .getAttributeValue("foreign-cols");
0431:                    if (foreignCols != null) {
0432:                        fkCols = new ArrayList<String>();
0433:                        List<String> aliases = Arrays.asList(foreignCols
0434:                                .split(","));
0435:
0436:                        /* resolve names */
0437:                        for (String col : aliases) {
0438:                            fkCols.add(entity.resolveName(col));
0439:                        }
0440:                    }
0441:
0442:                    ImportedKey importedKey = new ImportedKey(name, entity,
0443:                            pkEntity, fkCols);
0444:
0445:                    /* caching */
0446:                    String caching = keyelem.getAttributeValue("caching");
0447:                    if (checkSyntax("caching", caching, new String[] { "no",
0448:                            "yes" })) {
0449:                        importedKey.setCaching(caching.equals("yes"));
0450:                    }
0451:
0452:                    entity.addAttribute(importedKey);
0453:                }
0454:                for (Iterator exported = parent.getChildren("exported-key")
0455:                        .iterator(); exported.hasNext();) {
0456:                    Element keyelem = (Element) exported.next();
0457:                    String name = keyelem.getAttributeValue("name");
0458:                    if (name == null) {
0459:                        Logger
0460:                                .error("tag <exported-key> needs a 'name' attribute!");
0461:                        continue;
0462:                    }
0463:                    String pkEntity = keyelem.getAttributeValue("entity");
0464:                    if (pkEntity == null) {
0465:                        Logger
0466:                                .error("tag <exported-key> needs an 'entity' attribute (name='"
0467:                                        + name + "')!");
0468:                        continue;
0469:                    }
0470:                    List<String> fkCols = null;
0471:                    String foreignCols = keyelem
0472:                            .getAttributeValue("foreign-cols");
0473:                    if (foreignCols != null) {
0474:                        fkCols = new ArrayList<String>();
0475:                        List<String> aliases = Arrays.asList(foreignCols
0476:                                .split(","));
0477:
0478:                        /* resolve names */
0479:                        for (String col : aliases) {
0480:                            fkCols.add(entity.resolveName(col));
0481:                        }
0482:                    }
0483:                    ExportedKey exportedKey = new ExportedKey(name, entity,
0484:                            pkEntity, fkCols);
0485:
0486:                    /* caching */
0487:                    String caching = keyelem.getAttributeValue("caching");
0488:                    if (checkSyntax("caching", caching, new String[] { "no",
0489:                            "yes" })) {
0490:                        exportedKey.setCaching(caching.equals("yes"));
0491:                    }
0492:                    String order = keyelem.getAttributeValue("order");
0493:                    if (order != null) {
0494:                        exportedKey.setOrder(order);
0495:                    }
0496:
0497:                    entity.addAttribute(exportedKey);
0498:                }
0499:            }
0500:
0501:            /**
0502:             * Define actions.
0503:             * @param parent parent XML element
0504:             * @param entity parent entity
0505:             */
0506:            private void defineActions(Element parent, Entity entity) {
0507:                for (Iterator actions = parent.getChildren("action").iterator(); actions
0508:                        .hasNext();) {
0509:                    Element element = (Element) actions.next();
0510:                    String name = adaptCase(element.getAttributeValue("name"));
0511:                    Action action = null;
0512:                    if (isTransaction(element)) {
0513:                        Transaction transaction = new Transaction(name, entity);
0514:                        action = transaction;
0515:                        List<String> queries = new ArrayList<String>();
0516:                        List<List<String>> parameters = new ArrayList<List<String>>();
0517:                        StringBuilder query = new StringBuilder();
0518:                        List<String> paramNames = new ArrayList<String>();
0519:                        Iterator queryElements = element.getContent()
0520:                                .iterator();
0521:                        while (queryElements.hasNext()) {
0522:                            Object content = queryElements.next();
0523:                            if (content instanceof  Text) {
0524:                                String text = Strings
0525:                                        .trimSpacesAndEOL(((Text) content)
0526:                                                .getText());
0527:                                int i = text.indexOf(';');
0528:                                if (i != -1) {
0529:                                    query.append(text.substring(0, i));
0530:                                    queries.add(query.toString());
0531:                                    parameters.add(paramNames);
0532:                                    query = new StringBuilder();
0533:                                    paramNames = new ArrayList<String>();
0534:                                }
0535:                                query.append(text.substring(i + 1));
0536:                            } else {
0537:                                query.append(" ? ");
0538:                                Element elem = (Element) content;
0539:                                paramNames.add(elem.getName());
0540:                            }
0541:                        }
0542:                        if (query.length() > 0) {
0543:                            queries.add(query.toString());
0544:                            parameters.add(paramNames);
0545:                        }
0546:                        transaction.setQueries(queries);
0547:                        transaction.setParamNamesLists(parameters);
0548:                    } else { /* simple action */
0549:                        action = new Action(name, entity);
0550:                        String query = "";
0551:                        Iterator queryElements = element.getContent()
0552:                                .iterator();
0553:                        while (queryElements.hasNext()) {
0554:                            Object content = queryElements.next();
0555:                            if (content instanceof  Text) {
0556:                                query += Strings
0557:                                        .trimSpacesAndEOL(((Text) content)
0558:                                                .getText());
0559:                            } else {
0560:                                query += " ? ";
0561:                                Element elem = (Element) content;
0562:                                action.addParamName(adaptCase(elem.getName()));
0563:                            }
0564:                        }
0565:                        action.setQuery(query);
0566:                    }
0567:                    entity.addAction(action);
0568:                }
0569:            }
0570:
0571:            /**
0572:             * Define entities.
0573:             * @param database database XML element
0574:             * @throws Exception
0575:             */
0576:            private void defineEntities(Element database) throws Exception {
0577:                for (Iterator entities = database.getChildren("entity")
0578:                        .iterator(); entities.hasNext();) {
0579:                    Element element = (Element) entities.next();
0580:                    String origName = element.getAttributeValue("name");
0581:                    element.removeAttribute("name");
0582:                    String name = adaptCase(origName);
0583:                    String table = adaptCase(element.getAttributeValue("table"));
0584:                    element.removeAttribute("table");
0585:
0586:                    Entity entity = this .database
0587:                            .getEntityCreate(adaptCase(name));
0588:                    if (table != null) {
0589:                        entity.setTableName(table);
0590:                    }
0591:                    this .database.getReverseEngineer().addTableMatching(
0592:                            entity.getTableName(), entity);
0593:
0594:                    /* custom class */
0595:                    String cls = element.getAttributeValue("class");
0596:                    element.removeAttribute("class");
0597:                    if (cls != null) {
0598:                        try {
0599:                            Class clazz = Class.forName(cls);
0600:                            clazz.newInstance();
0601:                            /* looks ok */
0602:                            entity.setInstanceClass(cls);
0603:                        } catch (Throwable t) {
0604:                            Logger.error("Cannot instantiate class " + cls);
0605:                            Logger.log(t);
0606:                        }
0607:                    }
0608:
0609:                    /* access (deprecated) */
0610:                    String access = element.getAttributeValue("access");
0611:                    if (access != null) {
0612:                        Logger
0613:                                .warn("The syntax <entity access=\"rw|ro\"> is deprecated.");
0614:                        Logger
0615:                                .warn("Please use <entity read-only=\"true|false\"> instead.");
0616:                        if (checkSyntax(name + ".access", access, new String[] {
0617:                                "ro", "rw" })) {
0618:                            access = access.toLowerCase();
0619:                            if (access.equalsIgnoreCase("ro"))
0620:                                entity.setReadOnly(true);
0621:                            else if (access.equalsIgnoreCase("rw"))
0622:                                entity.setReadOnly(false);
0623:                        }
0624:                    }
0625:
0626:                    /* read-only */
0627:                    String ro = element.getAttributeValue("read-only");
0628:                    element.removeAttribute("read-only");
0629:                    if (ro != null) {
0630:                        /* check syntax but continue anyway with read-only database if the syntax is bad */
0631:                        checkSyntax("read-only", ro, new String[] { "true",
0632:                                "false" });
0633:                        /* default to true - using Boolean.parseBoolean is not possible */
0634:                        this .database
0635:                                .setReadOnly(!ro.equalsIgnoreCase("false"));
0636:                    }
0637:
0638:                    /* caching */
0639:                    String caching = element.getAttributeValue("caching");
0640:                    element.removeAttribute("caching");
0641:                    if (checkSyntax("caching", caching, new String[] { "none",
0642:                            "no", "yes", "soft", "full" }))
0643:                        entity.setCachingMethod(parseCaching(caching));
0644:
0645:                    /* obfuscation */
0646:                    String obfuscate = element.getAttributeValue("obfuscate");
0647:                    element.removeAttribute("obfuscate");
0648:                    if (obfuscate != null) {
0649:                        List<String> obfuscatedCols = new ArrayList<String>();
0650:                        StringTokenizer tokenizer = new StringTokenizer(
0651:                                obfuscate, ", ");
0652:                        while (tokenizer.hasMoreTokens()) {
0653:                            obfuscatedCols
0654:                                    .add(adaptCase(tokenizer.nextToken()));
0655:                        }
0656:                        entity.setObfuscated(obfuscatedCols);
0657:                    }
0658:
0659:                    /* localization */
0660:                    String localize = element.getAttributeValue("localize");
0661:                    element.removeAttribute("localize");
0662:                    if (localize != null) {
0663:                        List<String> localizedCols = new ArrayList<String>();
0664:                        StringTokenizer tokenizer = new StringTokenizer(
0665:                                localize, ", ");
0666:                        while (tokenizer.hasMoreTokens()) {
0667:                            localizedCols.add(adaptCase(tokenizer.nextToken()));
0668:                        }
0669:                        entity.setLocalized(localizedCols);
0670:                    }
0671:
0672:                    /* aliases */
0673:                    Element aliases = element.getChild("aliases");
0674:                    if (aliases != null) {
0675:                        for (org.jdom.Attribute att : (List<org.jdom.Attribute>) aliases
0676:                                .getAttributes()) {
0677:                            String column = att.getValue();
0678:                            String alias = att.getName();
0679:                            entity.addAlias(alias, column);
0680:                        }
0681:                    }
0682:
0683:                    /* define entity attributes */
0684:                    defineAttributes(element, entity);
0685:
0686:                    /* define entity actions */
0687:                    defineActions(element, entity);
0688:
0689:                    /* define entity imported and exported keys */
0690:                    defineForeignKeys(element, entity);
0691:
0692:                    /* define entity constraints */
0693:                    defineConstraints(element, entity);
0694:                }
0695:            }
0696:
0697:            /**
0698:             * Define constraints.
0699:             * @param element parent XML element
0700:             * @param entity parent entity
0701:             * @throws Exception
0702:             */
0703:            private void defineConstraints(Element element, Entity entity)
0704:                    throws Exception {
0705:                DateFormat format = new SimpleDateFormat("yyyyMMdd");
0706:                String str;
0707:                for (Iterator columns = element.getChildren("constraint")
0708:                        .iterator(); columns.hasNext();) {
0709:                    Element colElement = (Element) columns.next();
0710:                    String column = colElement.getAttributeValue("column");
0711:                    if (column == null) {
0712:                        Logger
0713:                                .error("constraint tag needs a 'column' attribute");
0714:                        continue;
0715:                    }
0716:                    colElement.removeAttribute("column");
0717:
0718:                    String type;
0719:                    boolean hasType = ((type = colElement
0720:                            .getAttributeValue("type")) != null);
0721:
0722:                    /* short-syntax length */
0723:                    int minLen = 0, maxLen = Integer.MAX_VALUE;
0724:                    String minstr = colElement.getAttributeValue("min-len");
0725:                    String maxstr = colElement.getAttributeValue("max-len");
0726:                    if (minstr != null || maxstr != null) {
0727:                        colElement.removeAttribute("min-len");
0728:                        colElement.removeAttribute("max-len");
0729:                        if (minstr != null) {
0730:                            minLen = Integer.parseInt(minstr);
0731:                        }
0732:                        if (maxstr != null) {
0733:                            maxLen = Integer.parseInt(maxstr);
0734:                        }
0735:                        entity
0736:                                .addConstraint(column, new Length(minLen,
0737:                                        maxLen));
0738:                    }
0739:                    /* short-syntax range */
0740:                    minstr = colElement.getAttributeValue("min");
0741:                    maxstr = colElement.getAttributeValue("max");
0742:                    if (minstr != null || maxstr != null || hasType
0743:                            && ("integer".equals(type) | "number".equals(type))) {
0744:                        colElement.removeAttribute("min");
0745:                        colElement.removeAttribute("max");
0746:                        Range numberConstraint = null;
0747:                        numberConstraint = new Range();
0748:                        if (minstr != null) {
0749:                            Number min = Double.parseDouble(minstr);
0750:                            numberConstraint.setMin(min);
0751:                        }
0752:                        if (maxstr != null) {
0753:                            Number max = Double.parseDouble(maxstr);
0754:                            numberConstraint.setMax(max);
0755:                        }
0756:                        if (hasType && "integer".equals(type)) {
0757:                            numberConstraint.setInteger(true);
0758:                            colElement.removeAttribute("type");
0759:                        }
0760:                        entity.addConstraint(column, numberConstraint);
0761:                    }
0762:                    /* short-syntax date range - use yyyyMMdd date format */
0763:                    String afterstr = colElement.getAttributeValue("after");
0764:                    String beforestr = colElement.getAttributeValue("before");
0765:                    if (afterstr != null || beforestr != null || hasType
0766:                            && "date".equals(type)) {
0767:                        colElement.removeAttribute("after");
0768:                        colElement.removeAttribute("before");
0769:                        DateRange dateConstraint = new DateRange();
0770:                        if (afterstr != null) {
0771:                            Date after = format.parse(afterstr);
0772:                            dateConstraint.setAfterDate(after);
0773:                        }
0774:                        if (beforestr != null) {
0775:                            Date before = format.parse(beforestr);
0776:                            dateConstraint.setBeforeDate(before);
0777:                        }
0778:                        if (hasType && "date".equals(type)) {
0779:                            colElement.removeAttribute("type");
0780:                        }
0781:                        entity.addConstraint(column, dateConstraint);
0782:                    }
0783:                    /* short-syntax, email */
0784:                    if (hasType && "email".equals(type)) {
0785:                        entity.addConstraint(column, new Email());
0786:                        colElement.removeAttribute("type");
0787:                    }
0788:                    /* short-syntax, others */
0789:                    for (Iterator atts = colElement.getAttributes().iterator(); atts
0790:                            .hasNext();) {
0791:                        org.jdom.Attribute attribute = (org.jdom.Attribute) atts
0792:                                .next();
0793:                        String name = attribute.getName();
0794:                        String value = attribute.getValue();
0795:                        if (name.equals("not-null")) {
0796:                            if (attribute.getBooleanValue()) {
0797:                                entity.addConstraint(column, new NotNull());
0798:                            }
0799:                        }
0800:                        if (name.equals("not-empty")) {
0801:                            if (attribute.getBooleanValue()) {
0802:                                entity.addConstraint(column, new NotEmpty());
0803:                            }
0804:                        } else if (name.equals("one-of")) {
0805:                            entity.addConstraint(column, new OneOf(Arrays
0806:                                    .asList(value.split(","))));
0807:                        } else if (name.equals("reference")) {
0808:                            int dot = value.indexOf(".");
0809:                            if (dot == -1 || dot == value.length() - 1) {
0810:                                Logger
0811:                                        .error("bad syntax for reference constraint (entity "
0812:                                                + entity.getName()
0813:                                                + ", column "
0814:                                                + column
0815:                                                + "). Should be 'table.column'.");
0816:                            } else {
0817:                                String table = value.substring(0, dot);
0818:                                String col = value.substring(dot + 1);
0819:                                entity.addConstraint(column, new Reference(
0820:                                        database, table, col));
0821:                            }
0822:                        } else if (name.equals("regex")) {
0823:                            entity.addConstraint(column, new Regex(Pattern
0824:                                    .compile(value)));
0825:                        } else {
0826:                            if (!name.equals("name")) {
0827:                                Logger.error("ignoring unknown constraint '"
0828:                                        + name + "=" + attribute.getValue()
0829:                                        + "' (entity " + entity.getName()
0830:                                        + ", column " + column + ").");
0831:                            }
0832:                        }
0833:                    }
0834:                    /* long syntax */
0835:                    Length length = null;
0836:                    for (Iterator constraints = colElement.getChildren()
0837:                            .iterator(); constraints.hasNext();) {
0838:                        Element constraintElement = (Element) constraints
0839:                                .next();
0840:                        String name = constraintElement.getName();
0841:                        FieldConstraint constraint = null;
0842:                        if (name.equals("email")) {
0843:                            boolean dnsCheck = false;
0844:                            boolean smtpCheck = false;
0845:                            str = constraintElement
0846:                                    .getAttributeValue("dns-check");
0847:                            if (checkSyntax("dns-check", str, new String[] {
0848:                                    "yes", "no" })) {
0849:                                dnsCheck = (str.equalsIgnoreCase("yes"));
0850:                            }
0851:                            str = constraintElement
0852:                                    .getAttributeValue("smtp-check");
0853:                            if (checkSyntax("smtp-check", str, new String[] {
0854:                                    "yes", "no" })) {
0855:                                smtpCheck = (str.equalsIgnoreCase("yes"));
0856:                            }
0857:                            constraint = new Email(dnsCheck, smtpCheck);
0858:                        } else if (name.equals("min-len")) {
0859:                            if (length != null) {
0860:                                length.setMinLength(Integer
0861:                                        .parseInt(constraintElement
0862:                                                .getAttributeValue("value")));
0863:                            } else {
0864:                                constraint = length = new Length(Integer
0865:                                        .parseInt(constraintElement
0866:                                                .getAttributeValue("value")),
0867:                                        Integer.MAX_VALUE);
0868:                            }
0869:                        } else if (name.equals("max-len")) {
0870:                            if (length != null) {
0871:                                length.setMaxLength(Integer
0872:                                        .parseInt(constraintElement
0873:                                                .getAttributeValue("value")));
0874:                            } else {
0875:                                constraint = length = new Length(0, Integer
0876:                                        .parseInt(constraintElement
0877:                                                .getAttributeValue("value")));
0878:                            }
0879:                        } else if (name.equals("integer")
0880:                                || name.equals("number")) {
0881:                            Range range = new Range();
0882:                            range.setInteger(name.equals("integer"));
0883:                            minstr = constraintElement.getAttributeValue("min");
0884:                            if (minstr != null) {
0885:                                range.setMin(Double.parseDouble(minstr));
0886:                            }
0887:                            maxstr = constraintElement.getAttributeValue("max");
0888:                            if (maxstr != null) {
0889:                                range.setMax(Double.parseDouble(maxstr));
0890:                            }
0891:                            constraint = range;
0892:                        } else if (name.equals("date")) {
0893:                            DateRange daterange = new DateRange();
0894:                            minstr = constraintElement
0895:                                    .getAttributeValue("after");
0896:                            if (minstr != null) {
0897:                                daterange.setAfterDate(format.parse(minstr));
0898:                            }
0899:                            maxstr = constraintElement
0900:                                    .getAttributeValue("before");
0901:                            if (maxstr != null) {
0902:                                daterange.setBeforeDate(format.parse(maxstr));
0903:                            }
0904:                            String dateformat = constraintElement
0905:                                    .getAttributeValue("format");
0906:                            if (dateformat != null) {
0907:                                daterange.setDateFormat(new SimpleDateFormat(
0908:                                        dateformat));
0909:                            }
0910:                            constraint = daterange;
0911:                        } else if (name.equals("not-null")) {
0912:                            constraint = new NotNull();
0913:                        } else if (name.equals("not-empty")) {
0914:                            constraint = new NotEmpty();
0915:                        } else if (name.equals("one-of")) {
0916:                            List<String> values = new ArrayList<String>();
0917:                            for (Iterator it = constraintElement.getChildren(
0918:                                    "value").iterator(); it.hasNext();) {
0919:                                values.add((String) ((Element) it.next())
0920:                                        .getText());
0921:                            }
0922:                            constraint = new OneOf(values);
0923:                        } else if (name.equals("reference")) {
0924:                            String fk = constraintElement
0925:                                    .getAttributeValue("foreign-key");
0926:                            if (fk == null) {
0927:                                Logger
0928:                                        .error("reference constraint needs a 'foreign-key' attribute");
0929:                            }
0930:                            int dot = fk.indexOf(".");
0931:                            if (dot == -1 || dot == fk.length() - 1) {
0932:                                Logger
0933:                                        .error("bad syntax for reference constraint (entity "
0934:                                                + entity.getName()
0935:                                                + ", column "
0936:                                                + column
0937:                                                + "). Should be 'table.column'.");
0938:                            } else {
0939:                                String table = fk.substring(0, dot);
0940:                                String col = fk.substring(dot + 1);
0941:                                constraint = new Reference(database, table, col);
0942:                            }
0943:                        } else if (name.equals("regex")) {
0944:                            constraint = new Regex(Pattern
0945:                                    .compile(constraintElement
0946:                                            .getAttributeValue("pattern")));
0947:                        } else {
0948:                            Logger
0949:                                    .error("ignoring unknown constraint '"
0950:                                            + name
0951:                                            + "' (entity \"+entity.getName()+\", column \"+column+\").");
0952:                        }
0953:                        if (constraint != null) {
0954:                            String msg = constraintElement
0955:                                    .getAttributeValue("message");
0956:                            if (msg != null) {
0957:                                constraint.setMessage(msg);
0958:                            }
0959:                            entity.addConstraint(column, constraint);
0960:                        }
0961:                    }
0962:                }
0963:            }
0964:
0965:            /** Check the syntax of a parameter in the config file.
0966:             *
0967:             * @param paramName name of the parameter
0968:             * @param paramValue value of the parameter
0969:             * @param possibleValues possible values for the parameter
0970:             * @return whether the syntax is correct
0971:             */
0972:            private boolean checkSyntax(String paramName, String paramValue,
0973:                    String[] possibleValues) {
0974:                if (paramValue == null)
0975:                    return false;
0976:                List possible = Arrays.asList(possibleValues);
0977:                if (paramValue != null
0978:                        && Arrays.asList(possibleValues).contains(
0979:                                paramValue.toLowerCase()))
0980:                    return true;
0981:                else {
0982:                    Logger.error("Parameter '" + paramName + "' wants one of: "
0983:                            + StringLists.join(possible, ","));
0984:                    return false;
0985:                }
0986:            }
0987:
0988:            /** Parse a caching value.
0989:             *
0990:             * @param caching string describing the type of caching
0991:             * @return type of caching
0992:             */
0993:            private static int parseCaching(String caching) {
0994:                return caching == null || caching.equalsIgnoreCase("none")
0995:                        || caching.equalsIgnoreCase("no") ? Cache.NO_CACHE
0996:                        : caching.equalsIgnoreCase("soft")
0997:                                || caching.equalsIgnoreCase("yes") ? Cache.SOFT_CACHE
0998:                                : caching.equalsIgnoreCase("full") ? Cache.FULL_CACHE
0999:                                        : Cache.NO_CACHE;
1000:            }
1001:
1002:            /** Check whether the action defined by this XML tree is a simple action or a transaction.
1003:             *
1004:             * @param element XML tree defining an action
1005:             * @return true if the action is a transaction
1006:             */
1007:            public static boolean isTransaction(Element element) {
1008:                Iterator queryElements = element.getContent().iterator();
1009:                while (queryElements.hasNext()) {
1010:                    Object content = queryElements.next();
1011:                    if (content instanceof  Text) {
1012:                        String text = Strings.trimSpacesAndEOL(((Text) content)
1013:                                .getText());
1014:                        char[] chars = text.toCharArray();
1015:                        boolean insideLitteral = false;
1016:                        for (int i = 0; i < chars.length; i++) {
1017:                            if (chars[i] == '\'')
1018:                                insideLitteral = !insideLitteral;
1019:                            else if (!insideLitteral && chars[i] == ';'
1020:                                    && i < chars.length - 1)
1021:                                return true;
1022:                        }
1023:                    }
1024:                }
1025:                return false;
1026:            }
1027:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.