Source Code Cross Referenced for SQLValidationVisitor.java in  » IDE-Netbeans » etl.project » org » netbeans » modules » sql » framework » model » visitors » 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 » IDE Netbeans » etl.project » org.netbeans.modules.sql.framework.model.visitors 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:        package org.netbeans.modules.sql.framework.model.visitors;
0042:
0043:        import java.sql.Types;
0044:        import java.util.ArrayList;
0045:        import java.util.Collection;
0046:        import java.util.Collections;
0047:        import java.util.HashSet;
0048:        import java.util.Iterator;
0049:        import java.util.List;
0050:        import java.util.Map;
0051:        import org.axiondb.AxionException;
0052:        import org.axiondb.parser.AxionDateTimeFormatParser;
0053:        import org.netbeans.modules.sql.framework.model.DBColumn;
0054:        import org.netbeans.modules.sql.framework.common.jdbc.SQLUtils;
0055:        import org.netbeans.modules.sql.framework.common.utils.PhysicalTable;
0056:        import org.netbeans.modules.sql.framework.model.ColumnRef;
0057:        import org.netbeans.modules.sql.framework.model.RuntimeInput;
0058:        import org.netbeans.modules.sql.framework.model.SQLCaseOperator;
0059:        import org.netbeans.modules.sql.framework.model.SQLCastOperator;
0060:        import org.netbeans.modules.sql.framework.model.SQLCondition;
0061:        import org.netbeans.modules.sql.framework.model.SQLConnectableObject;
0062:        import org.netbeans.modules.sql.framework.model.SQLConstants;
0063:        import org.netbeans.modules.sql.framework.model.SQLDBColumn;
0064:        import org.netbeans.modules.sql.framework.model.SQLDefinition;
0065:        import org.netbeans.modules.sql.framework.model.SQLFilter;
0066:        import org.netbeans.modules.sql.framework.model.SQLGenericOperator;
0067:        import org.netbeans.modules.sql.framework.model.SQLGroupBy;
0068:        import org.netbeans.modules.sql.framework.model.SQLInputObject;
0069:        import org.netbeans.modules.sql.framework.model.SQLJoinOperator;
0070:        import org.netbeans.modules.sql.framework.model.SQLJoinView;
0071:        import org.netbeans.modules.sql.framework.model.SQLLiteral;
0072:        import org.netbeans.modules.sql.framework.model.SQLObject;
0073:        import org.netbeans.modules.sql.framework.model.SQLPredicate;
0074:        import org.netbeans.modules.sql.framework.model.SQLWhen;
0075:        import org.netbeans.modules.sql.framework.model.SourceColumn;
0076:        import org.netbeans.modules.sql.framework.model.SourceTable;
0077:        import org.netbeans.modules.sql.framework.model.TargetColumn;
0078:        import org.netbeans.modules.sql.framework.model.TargetTable;
0079:        import org.netbeans.modules.sql.framework.model.ValidationInfo;
0080:        import org.netbeans.modules.sql.framework.model.impl.SQLCustomOperatorImpl;
0081:        import org.netbeans.modules.sql.framework.model.impl.ValidationInfoImpl;
0082:        import org.netbeans.modules.sql.framework.model.utils.SQLObjectUtil;
0083:        import org.openide.util.NbBundle;
0084:        import com.sun.sql.framework.exception.BaseException;
0085:        import com.sun.sql.framework.jdbc.DBConstants;
0086:        import net.java.hulp.i18n.Logger;
0087:        import com.sun.sql.framework.utils.StringUtil;
0088:        import org.netbeans.modules.etl.logger.Localizer;
0089:        import org.netbeans.modules.etl.logger.LogUtil;
0090:        import org.netbeans.modules.sql.framework.model.Index;
0091:
0092:        /**
0093:         * @author Ritesh Adval
0094:         * @version $Revision$
0095:         */
0096:        public class SQLValidationVisitor implements  SQLVisitor {
0097:
0098:            private static transient final Logger mLogger = LogUtil
0099:                    .getLogger(SQLValidationVisitor.class.getName());
0100:            private static transient final Localizer mLoc = Localizer.get();
0101:            private static final HashSet<String> DATE_FORMAT_OPS = new HashSet<String>();
0102:
0103:            static {
0104:                DATE_FORMAT_OPS.add("isvaliddatetime");
0105:                DATE_FORMAT_OPS.add("chartodate");
0106:                DATE_FORMAT_OPS.add("datetochar");
0107:            }
0108:            private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
0109:            private static final String LOG_CATEGORY = SQLValidationVisitor.class
0110:                    .getName();
0111:            private List<ValidationInfo> validationInfoList = new ArrayList<ValidationInfo>();
0112:
0113:            public List<ValidationInfo> getValidationInfoList() {
0114:                return this .validationInfoList;
0115:            }
0116:
0117:            /**
0118:             * Indicates whether the given List of ValidationInfo instances contains at least one
0119:             * validation error.
0120:             *
0121:             * @param valInfoList Collection of ValidationInfo instances to be evaluated.
0122:             * @return true if at least one item in <code>valInfoList</code> is an error.
0123:             */
0124:            public boolean hasErrors(Collection valInfoList) {
0125:                boolean ret = false;
0126:
0127:                if (valInfoList != null) {
0128:                    Iterator itr = valInfoList.iterator();
0129:                    ValidationInfo vInfo = null;
0130:
0131:                    while (itr.hasNext()) {
0132:                        vInfo = (ValidationInfo) itr.next();
0133:                        if (vInfo.getValidationType() == ValidationInfo.VALIDATION_ERROR) {
0134:                            ret = true;
0135:                            break;
0136:                        }
0137:                    }
0138:                }
0139:                return ret;
0140:            }
0141:
0142:            public void visit(SourceTable sourceTable) {
0143:                // validate extraction condition
0144:                SQLCondition extCondition = sourceTable
0145:                        .getExtractionCondition();
0146:                if (extCondition != null) {
0147:                    if (!extCondition.isValid()) {
0148:                        String desc = buildErrorMessageWithObjectIdentifier(
0149:                                sourceTable.getQualifiedName(),
0150:                                "ERROR_extraction_condition_invalid");
0151:                        ValidationInfo validationInfo = new ValidationInfoImpl(
0152:                                extCondition, desc,
0153:                                ValidationInfo.VALIDATION_ERROR);
0154:                        validationInfoList.add(validationInfo);
0155:                    } else {
0156:                        visit(extCondition);
0157:                    }
0158:                }
0159:
0160:                // FIXME: This condition when reported and user tries to
0161:                // edit it by double clicking then extraction condition content is shown
0162:                // validate data validation condition
0163:                SQLCondition dataValidationCondition = sourceTable
0164:                        .getDataValidationCondition();
0165:                if (dataValidationCondition != null) {
0166:                    if (!dataValidationCondition.isValid()) {
0167:                        String desc = buildErrorMessageWithObjectIdentifier(
0168:                                sourceTable.getQualifiedName(),
0169:                                "ERROR_datavalidation_condition_invalid");
0170:                        ValidationInfo validationInfo = new ValidationInfoImpl(
0171:                                dataValidationCondition, desc,
0172:                                ValidationInfo.VALIDATION_ERROR);
0173:                        validationInfoList.add(validationInfo);
0174:                    } else {
0175:                        visit(dataValidationCondition);
0176:                    }
0177:                }
0178:            }
0179:
0180:            public void visit(SQLCaseOperator operator) {
0181:                visitExpression(operator, true);
0182:            }
0183:
0184:            public void visit(SQLCondition condition) {
0185:                // If there is no condition then do not validate
0186:                if (!condition.isConditionDefined()) {
0187:                    return;
0188:                }
0189:
0190:                // If the resulting expression does not form a valid condition, then raise an
0191:                // error.
0192:                if (!condition.isValid()) {
0193:                    String nbBundle1 = mLoc
0194:                            .t("PRSR001: Condition is not valid.");
0195:                    String error = Localizer.parse(nbBundle1);
0196:                    ValidationInfo info = new ValidationInfoImpl(null, error,
0197:                            ValidationInfo.VALIDATION_ERROR);
0198:                    validationInfoList.add(info);
0199:                }
0200:
0201:                Collection allObjects = condition.getAllObjects();
0202:                List expObjects = SQLObjectUtil
0203:                        .getAllExpressionObjects(allObjects);
0204:                // Validate all other objects in objectMap
0205:                validate(allObjects, expObjects);
0206:            }
0207:
0208:            public void visit(SQLDefinition definition) {
0209:                Iterator it = definition.getTargetTables().iterator();
0210:                boolean oracleTableGroupByUse = false;
0211:                final int execStrategy = definition.getExecutionStrategyCode()
0212:                        .intValue();
0213:                if ((execStrategy == SQLDefinition.EXECUTION_STRATEGY_STAGING)
0214:                        && definition.requiresPipelineProcess()) {
0215:                    String nbBundle2 = mLoc
0216:                            .t("PRSR001: Cannot execute in Staging mode, choose Best-fit or Pipeline.");
0217:                    String desc = Localizer.parse(nbBundle2);
0218:                    ValidationInfo validationInfo = new ValidationInfoImpl(
0219:                            definition, desc, ValidationInfo.VALIDATION_ERROR);
0220:                    validationInfoList.add(validationInfo);
0221:                }
0222:
0223:                List<PhysicalTable> srcTables = new ArrayList<PhysicalTable>();
0224:                List<PhysicalTable> trgtTables = new ArrayList<PhysicalTable>();
0225:                while (it.hasNext()) {
0226:                    TargetTable targetTable = (TargetTable) it.next();
0227:                    final String identifier = targetTable.getQualifiedName();
0228:                    final int stmtType = targetTable.getStatementType();
0229:                    String dbType = targetTable.getParent()
0230:                            .getConnectionDefinition().getDBType();
0231:                    final String jdbcUrl = targetTable.getParent()
0232:                            .getConnectionDefinition().getConnectionURL();
0233:                    boolean jdbcEway = isJdbcOrUnknownDB(dbType, jdbcUrl);
0234:
0235:                    boolean oracleTargetTableWithCondition = false;
0236:                    boolean oracleSourceTable = false;
0237:
0238:                    // Check for Unknown DB and UPDATE and MERGE statement usage.
0239:                    if (jdbcEway) {
0240:                        if ((stmtType == SQLConstants.INSERT_UPDATE_STATEMENT)
0241:                                && ((execStrategy == SQLDefinition.EXECUTION_STRATEGY_BEST_FIT) || (execStrategy == SQLDefinition.EXECUTION_STRATEGY_STAGING))) {
0242:                            String desc = buildErrorMessageWithObjectIdentifier(
0243:                                    identifier,
0244:                                    "WARN_merge_may_not_be_supported");
0245:                            ValidationInfo validationInfo = new ValidationInfoImpl(
0246:                                    targetTable, desc,
0247:                                    ValidationInfo.VALIDATION_WARNING);
0248:                            validationInfoList.add(validationInfo);
0249:                        }
0250:                    }
0251:
0252:                    targetTable.visit(this );
0253:
0254:                    trgtTables.add(PhysicalTable.getPhysicalTable(targetTable));
0255:                    try {
0256:                        srcTables.addAll(PhysicalTable
0257:                                .getPhysicalTableList(targetTable
0258:                                        .getSourceTableList()));
0259:                    } catch (BaseException e) {
0260:                        String nbBundle3 = mLoc
0261:                                .t("PRSR001: Must have at least one column mapped to a literal, source column or operator.");
0262:                        String desc = Localizer.parse(nbBundle3);
0263:                        ValidationInfo validationInfo = new ValidationInfoImpl(
0264:                                targetTable, desc,
0265:                                ValidationInfo.VALIDATION_ERROR);
0266:                        validationInfoList.add(validationInfo);
0267:                    }
0268:
0269:                    if ((targetTable.getJoinCondition() != null)
0270:                            && (targetTable.getJoinCondition()
0271:                                    .isConditionDefined())) {
0272:                        dbType = targetTable.getParent()
0273:                                .getConnectionDefinition().getDBType();
0274:                        dbType = (dbType != null) ? dbType.toUpperCase() : "";
0275:                        if (dbType.indexOf(DBConstants.ORACLE_STR) >= 0) {
0276:                            oracleTargetTableWithCondition = true;
0277:                        }
0278:                    }
0279:
0280:                    try {
0281:                        Iterator srcItr = targetTable.getSourceTableList()
0282:                                .iterator();
0283:                        SourceTable srcTbl = null;
0284:                        while (srcItr.hasNext()) {
0285:                            srcTbl = (SourceTable) srcItr.next();
0286:                            dbType = srcTbl.getParent()
0287:                                    .getConnectionDefinition().getDBType();
0288:                            dbType = (dbType != null) ? dbType.toUpperCase()
0289:                                    : "";
0290:                            if (dbType.indexOf(DBConstants.ORACLE_STR) >= 0) {
0291:                                oracleSourceTable = true;
0292:                                break;
0293:                            }
0294:                        }
0295:                    } catch (BaseException ex) {
0296:                        // ignore
0297:                    }
0298:
0299:                    if ((targetTable.getSQLGroupBy() != null)
0300:                            && (targetTable.getSQLGroupBy().getColumns().size() > 0)) {
0301:                        if (oracleTargetTableWithCondition || oracleSourceTable) {
0302:                            oracleTableGroupByUse = true;
0303:                        }
0304:                    }
0305:                }
0306:
0307:                for (it = trgtTables.iterator(); it.hasNext();) {
0308:                    PhysicalTable pt = (PhysicalTable) it.next();
0309:                    if (srcTables.contains(pt)) {
0310:                        String nbBundle4 = mLoc.t(
0311:                                "PRSR001: {0} used as both source and target.",
0312:                                pt.getName());
0313:                        String desc = Localizer.parse(nbBundle4);
0314:                        ValidationInfo validationInfo = new ValidationInfoImpl(
0315:                                definition, desc,
0316:                                ValidationInfo.VALIDATION_WARNING);
0317:                        validationInfoList.add(validationInfo);
0318:                    }
0319:                }
0320:
0321:                // Flag error when one of the source tables is Oracle, Group By clause
0322:                // is used and Pipeline is required.
0323:                // Since we use Oracle forward only ResultSet to avoid OutOfMemoryError,
0324:                // as its scroll-able result set caches data at the client VM.
0325:                // Pipeline GROUP BY processing needs scroll-able result set.
0326:                if ((definition.requiresPipelineProcess() || (definition
0327:                        .getExecutionStrategyCode().intValue() == SQLDefinition.EXECUTION_STRATEGY_PIPELINE))
0328:                        && (oracleTableGroupByUse)) {
0329:                    String nbBundle5 = mLoc
0330:                            .t("PRSR001: Can not use Oracle table as Source with Group By clause in pipeline/validation mode.");
0331:                    String desc = Localizer.parse(nbBundle5);
0332:                    ValidationInfo validationInfo = new ValidationInfoImpl(
0333:                            definition, desc, ValidationInfo.VALIDATION_ERROR);
0334:                    validationInfoList.add(validationInfo);
0335:                }
0336:            }
0337:
0338:            public void visit(SQLFilter filter) {
0339:                visitExpression(filter, true);
0340:
0341:                if (!filter.isValid()) {
0342:                    String nbBundle6 = mLoc.t("PRSR001: {0} {1}", filter
0343:                            .getDisplayName(), filter.toString());
0344:                    String descriptor = Localizer.parse(nbBundle6);
0345:                    String message = buildErrorMessageWithObjectIdentifier(
0346:                            descriptor, "ERROR_predicate_invalid");
0347:                    ValidationInfo expValidationInfo = new ValidationInfoImpl(
0348:                            filter, message, ValidationInfo.VALIDATION_ERROR);
0349:                    validationInfoList.add(expValidationInfo);
0350:                }
0351:
0352:                // Check if the next SQLFilter clause, if any, has a prefix.
0353:                if (filter.getNextFilter() != null
0354:                        && StringUtil.isNullString(filter.getNextFilter()
0355:                                .getPrefix())) {
0356:                    String nbBundle7 = mLoc.t("PRSR001: {0} {1}", filter
0357:                            .getNextFilter().getDisplayName(), filter
0358:                            .toString());
0359:                    String descriptor = Localizer.parse(nbBundle7);
0360:                    String message = buildErrorMessageWithObjectIdentifier(
0361:                            descriptor, "ERROR_predicate_missing_prefix");
0362:
0363:                    ValidationInfo expValidationInfo = new ValidationInfoImpl(
0364:                            filter, message, ValidationInfo.VALIDATION_ERROR);
0365:                    validationInfoList.add(expValidationInfo);
0366:                }
0367:            }
0368:
0369:            public void visit(SQLGenericOperator operator) {
0370:                if (operator.hasVariableArgs()
0371:                        && operator.getInputObjectMap().size() == 0) {
0372:                    String desc = buildErrorMessageWithObjectIdentifier(
0373:                            operator.getDisplayName(), "ERROR_input_not_linked");
0374:                    ValidationInfo expValidationInfo = new ValidationInfoImpl(
0375:                            operator, desc, ValidationInfo.VALIDATION_ERROR);
0376:                    validationInfoList.add(expValidationInfo);
0377:                } else {
0378:                    visitExpression(operator, true);
0379:                }
0380:            }
0381:
0382:            public void visit(SQLJoinOperator operator) {
0383:                doJoinConditionValidation(operator);
0384:                visitExpression(operator, true);
0385:            }
0386:
0387:            public void visit(SQLJoinView joinView) {
0388:                SQLJoinOperator rJoin = joinView.getRootJoin();
0389:                if (rJoin != null) {
0390:                    rJoin.visit(this );
0391:                }
0392:            }
0393:
0394:            public void visit(SQLPredicate operator) {
0395:                visitExpression(operator, true);
0396:            }
0397:
0398:            public void visit(SQLWhen when) {
0399:            }
0400:
0401:            private boolean isJdbcOrUnknownDB(String dbType, String jdbcUrl) {
0402:                boolean unknownDB = true;
0403:                if (dbType != null) {
0404:                    dbType = dbType.toUpperCase();
0405:                    for (int i = 0; i < DBConstants.SUPPORTED_DB_TYPE_STRINGS.length; i++) {
0406:                        if ((dbType
0407:                                .indexOf(DBConstants.SUPPORTED_DB_TYPE_STRINGS[i])) > -1) {
0408:                            unknownDB = false;
0409:                            break;
0410:                        }
0411:                    }
0412:
0413:                    // Now check whether connecting to known DB thru JDBC eWay
0414:                    if ((unknownDB) && (jdbcUrl != null)) {
0415:                        jdbcUrl = jdbcUrl.toLowerCase();
0416:                        for (int i = 0; i < DBConstants.SUPPORTED_DB_URL_PREFIXES.length; i++) {
0417:                            if ((jdbcUrl
0418:                                    .indexOf(DBConstants.SUPPORTED_DB_URL_PREFIXES[i])) > -1) {
0419:                                unknownDB = false;
0420:                                break;
0421:                            }
0422:                        }
0423:                    }
0424:                }
0425:                return unknownDB;
0426:            }
0427:
0428:            public void visit(TargetTable targetTable) {
0429:                final String identifier = targetTable.getQualifiedName();
0430:                final int stmtType = targetTable.getStatementType();
0431:
0432:                Collection<String> uniqueIndexColumns = new HashSet<String>();
0433:                List<Index> indexes = targetTable.getIndexes();
0434:                Index index = null;
0435:
0436:                if (indexes != null) {
0437:                    Iterator<Index> indexItr = indexes.iterator();
0438:                    while (indexItr.hasNext()) {
0439:                        index = indexItr.next();
0440:                        if (index.isUnique()) {
0441:                            uniqueIndexColumns.addAll(index.getColumnNames());
0442:                        }
0443:                    }
0444:                }
0445:
0446:                int nonNullColumns = findColumnErrors(targetTable, identifier,
0447:                        stmtType, uniqueIndexColumns);
0448:                validateGroupBy(targetTable, stmtType);
0449:                validateTargetTableCondition(targetTable, identifier, stmtType);
0450:
0451:                // check for column maps for non-delete statements
0452:                if (stmtType != SQLConstants.DELETE_STATEMENT) {
0453:                    if (nonNullColumns == 0) {
0454:                        String desc = buildErrorMessageWithObjectIdentifier(
0455:                                identifier, "ERROR_targettable_not_mapped");
0456:                        ValidationInfo validationInfo = new ValidationInfoImpl(
0457:                                targetTable, desc,
0458:                                ValidationInfo.VALIDATION_ERROR);
0459:                        validationInfoList.add(validationInfo);
0460:                    }
0461:                }
0462:
0463:                // do join view validation
0464:                SQLJoinView joinView = targetTable.getJoinView();
0465:                if (joinView != null) {
0466:                    joinView.visit(this );
0467:                }
0468:                validateSourceTableCondition(targetTable);
0469:
0470:                // validate truncate before load option
0471:                if (targetTable.isTruncateBeforeLoad()) {
0472:                    if (stmtType == SQLConstants.INSERT_STATEMENT) {
0473:                        ValidationInfo validationInfo = new ValidationInfoImpl(
0474:                                targetTable,
0475:                                "Target table "
0476:                                        + targetTable.getFullyQualifiedName()
0477:                                        + " will be truncated before loading, use this option if you want to refresh the data",
0478:                                ValidationInfo.VALIDATION_WARNING);
0479:                        validationInfoList.add(validationInfo);
0480:                    } else {
0481:                        ValidationInfo validationInfo = new ValidationInfoImpl(
0482:                                targetTable,
0483:                                "Can't truncate target table "
0484:                                        + targetTable.getFullyQualifiedName()
0485:                                        + " for the selected statement type -> "
0486:                                        + targetTable.getStrStatementType(),
0487:                                ValidationInfo.VALIDATION_ERROR);
0488:                        validationInfoList.add(validationInfo);
0489:                    }
0490:                }
0491:            }
0492:
0493:            private String buildErrorMessageWithObjectIdentifier(
0494:                    String identifier, String errorKey) {
0495:                return buildErrorMessageWithObjectIdentifiers(identifier,
0496:                        errorKey, EMPTY_OBJECT_ARRAY);
0497:            }
0498:
0499:            private String buildErrorMessageWithObjectIdentifiers(
0500:                    String identifier, String errorKey, Object[] errorParams) {
0501:                String nbBundle12 = mLoc.t("PRSR001: {0}-{1}", errorKey,
0502:                        errorParams);
0503:                String errorMessage = Localizer.parse(nbBundle12);
0504:                String nbBundle8 = mLoc.t("PRSR001: {0}-{1}", identifier,
0505:                        errorMessage);
0506:                return Localizer.parse(nbBundle8);
0507:            }
0508:
0509:            private void doJoinConditionValidation(SQLJoinOperator operator) {
0510:                // If join condition is not defined then warn user about a Cartesian join being
0511:                // created
0512:                String identifier = "";
0513:                SQLJoinView joinView = (SQLJoinView) operator.getParentObject();
0514:                if (joinView != null) {
0515:                    identifier = joinView.getQualifiedName();
0516:                }
0517:
0518:                SQLCondition jCondition = operator.getJoinCondition();
0519:                if (!jCondition.isConditionDefined()) {
0520:                    String desc = buildErrorMessageWithObjectIdentifier(
0521:                            identifier, "WARNING_join_condition_missing");
0522:                    ValidationInfoImpl vInfo = new ValidationInfoImpl(
0523:                            jCondition, desc, ValidationInfo.VALIDATION_WARNING);
0524:                    validationInfoList.add(vInfo);
0525:                } else {
0526:                    if (!jCondition.isValid()) {
0527:                        String desc = buildErrorMessageWithObjectIdentifier(
0528:                                identifier, "ERROR_join_condition_invalid");
0529:                        ValidationInfoImpl vInfo = new ValidationInfoImpl(
0530:                                jCondition, desc,
0531:                                ValidationInfo.VALIDATION_ERROR);
0532:                        validationInfoList.add(vInfo);
0533:                    }
0534:                }
0535:
0536:                // TODO Check whether this is too restrictive - shouldn't user be able to create
0537:                // arbitrary join conditions?
0538:                try {
0539:                    // check for at least one = condition between columns of the two joined table.
0540:                    // also check whether such columns are primary
0541:                    SQLPredicate rootPredicate = jCondition.getRootPredicate();
0542:                    if (rootPredicate != null) {
0543:                        SQLFilter filter = SQLPredicateVisitor
0544:                                .visit(rootPredicate);
0545:                        boolean foundOneEqualOp = false;
0546:                        boolean foundOnePKMatch = false;
0547:                        String pkMsg = null;
0548:
0549:                        while (filter != null) {
0550:                            SQLObject leftObj = filter
0551:                                    .getSQLObject(SQLFilter.LEFT);
0552:                            SQLObject rightObj = filter
0553:                                    .getSQLObject(SQLFilter.RIGHT);
0554:                            String op = filter.getOperator();
0555:
0556:                            if (isValidJoinOperator(op)) {
0557:                                if (leftObj.getObjectType() == SQLConstants.COLUMN_REF) {
0558:                                    leftObj = ((ColumnRef) leftObj).getColumn();
0559:                                }
0560:
0561:                                if (rightObj.getObjectType() == SQLConstants.COLUMN_REF) {
0562:                                    rightObj = ((ColumnRef) rightObj)
0563:                                            .getColumn();
0564:                                }
0565:
0566:                                SourceColumn sLeft = getFirstSourceColumnReferencedIn(leftObj);
0567:                                SourceColumn sRight = getFirstSourceColumnReferencedIn(rightObj);
0568:
0569:                                if (sLeft != null && sRight != null) {
0570:                                    foundOneEqualOp = true;
0571:                                    String errorKey = null;
0572:                                    Object[] objectNames = EMPTY_OBJECT_ARRAY;
0573:
0574:                                    if (sLeft.isPrimaryKey()
0575:                                            && sRight.isPrimaryKey()) {
0576:                                        foundOnePKMatch = true;
0577:                                    } else if (sLeft.isPrimaryKey()
0578:                                            && !sRight.isPrimaryKey()) {
0579:                                        errorKey = "ERROR_join_column_not_pk";
0580:                                        objectNames = new Object[] { sRight
0581:                                                .toString() };
0582:                                    } else if (!sLeft.isPrimaryKey()
0583:                                            && sRight.isPrimaryKey()) {
0584:                                        errorKey = "ERROR_join_column_not_pk";
0585:                                        objectNames = new Object[] { sLeft
0586:                                                .toString() };
0587:                                    } else {
0588:                                        errorKey = "ERROR_join_columns_not_pks";
0589:                                        objectNames = new Object[] {
0590:                                                sLeft.toString(),
0591:                                                sRight.toString() };
0592:                                    }
0593:
0594:                                    if (errorKey != null) {
0595:                                        pkMsg = buildErrorMessageWithObjectIdentifiers(
0596:                                                identifier, errorKey,
0597:                                                objectNames);
0598:                                    }
0599:                                }
0600:                            }
0601:
0602:                            filter = filter.getNextFilter();
0603:                        }
0604:
0605:                        // If an equal relation is not found between columns of both tables
0606:                        // then this is an error in join condition
0607:                        if (!foundOneEqualOp) {
0608:                            String desc = buildErrorMessageWithObjectIdentifier(
0609:                                    identifier, "ERROR_join_missing_equal_op");
0610:                            ValidationInfoImpl vInfo = new ValidationInfoImpl(
0611:                                    jCondition, desc,
0612:                                    ValidationInfo.VALIDATION_WARNING);
0613:                            validationInfoList.add(vInfo);
0614:                        } else if (!foundOnePKMatch) {
0615:                            String desc = pkMsg;
0616:                            ValidationInfoImpl vInfo = new ValidationInfoImpl(
0617:                                    jCondition, desc,
0618:                                    ValidationInfo.VALIDATION_WARNING);
0619:                            validationInfoList.add(vInfo);
0620:                        }
0621:
0622:                    }
0623:                } catch (BaseException ex) {
0624:                    mLogger
0625:                            .errorNoloc(
0626:                                    mLoc
0627:                                            .t(
0628:                                                    "PRSR130: Error while validating SQLJoinOperator-{0}",
0629:                                                    operator.getDisplayName()),
0630:                                    ex);
0631:                }
0632:            }
0633:
0634:            private int findColumnErrors(TargetTable targetTable,
0635:                    final String identifier, int stmtType,
0636:                    Collection uniqueIndexColumns) {
0637:                int nonNullColumns = 0;
0638:                List<ValidationInfo> columnErrors = new ArrayList<ValidationInfo>(
0639:                        5);
0640:                Iterator iter = targetTable.getColumns().values().iterator();
0641:                while (iter.hasNext()) {
0642:                    TargetColumn col = (TargetColumn) iter.next();
0643:                    String argName = col.getName();
0644:                    SQLObject obj = col.getValue();
0645:
0646:                    switch (stmtType) {
0647:                    case SQLConstants.DELETE_STATEMENT:
0648:                        // Columns must not be linked for delete statement.
0649:                        if (obj != null) {
0650:                            String desc = buildErrorMessageWithObjectIdentifiers(
0651:                                    identifier,
0652:                                    "ERROR_input_link_prohibited_delete",
0653:                                    new Object[] { argName });
0654:                            columnErrors.add(new ValidationInfoImpl(
0655:                                    targetTable, desc,
0656:                                    ValidationInfo.VALIDATION_ERROR));
0657:                        }
0658:                        break;
0659:                    case SQLConstants.UPDATE_STATEMENT:
0660:                        // PK and not null columns don't need to be linked for update
0661:                        // statement.
0662:                        break;
0663:                    default:
0664:                        if ((col.isPrimaryKey() || !col.isNullable())
0665:                                && obj == null) {
0666:                            String desc = buildErrorMessageWithObjectIdentifiers(
0667:                                    identifier,
0668:                                    "WARNING_input_link_needed_pknotnull",
0669:                                    new Object[] { argName });
0670:                            columnErrors.add(new ValidationInfoImpl(
0671:                                    targetTable, desc,
0672:                                    ValidationInfo.VALIDATION_WARNING));
0673:                        } else if (uniqueIndexColumns.contains(col.getName())
0674:                                && (obj == null)) {
0675:                            String desc = buildErrorMessageWithObjectIdentifiers(
0676:                                    identifier,
0677:                                    "WARNING_input_link_needed_unique",
0678:                                    new Object[] { argName });
0679:                            columnErrors.add(new ValidationInfoImpl(
0680:                                    targetTable, desc,
0681:                                    ValidationInfo.VALIDATION_WARNING));
0682:                        }
0683:
0684:                        break;
0685:                    }
0686:
0687:                    // Validate the column input against the declared datatype for this column.
0688:                    if (obj != null) {
0689:                        ValidationInfo expValidationInfo = validateInputDataType(
0690:                                targetTable, argName, col.getDisplayName(), obj);
0691:                        if (expValidationInfo != null) {
0692:                            columnErrors.add(expValidationInfo);
0693:                        }
0694:                    }
0695:
0696:                    if (columnErrors.size() != 0) {
0697:                        validationInfoList.addAll(columnErrors);
0698:                        columnErrors.clear();
0699:                    }
0700:
0701:                    if (obj != null) {
0702:                        nonNullColumns++;
0703:                        if (obj instanceof  SQLConnectableObject) {
0704:                            SQLConnectableObject inObj = (SQLConnectableObject) obj;
0705:                            inObj.visit(this );
0706:                        }
0707:                    }
0708:                }
0709:                return nonNullColumns;
0710:            }
0711:
0712:            /**
0713:             * Gets the first column, if any, associated with a source table that is referenced as
0714:             * an input within the given SQLObject.
0715:             *
0716:             * @param sqlObj SQLObject whose inputs are to be traversed
0717:             * @return first SourceColumn input encountered, or null if none are encountered
0718:             */
0719:            private SourceColumn getFirstSourceColumnReferencedIn(
0720:                    SQLObject sqlObj) {
0721:                if (sqlObj instanceof  SourceColumn) {
0722:                    Object parent = ((SourceColumn) sqlObj).getParent();
0723:                    return (parent instanceof  RuntimeInput) ? null
0724:                            : (SourceColumn) sqlObj;
0725:                } else if (sqlObj instanceof  ColumnRef) {
0726:                    return getFirstSourceColumnReferencedIn(((ColumnRef) sqlObj)
0727:                            .getColumn());
0728:                } else if (sqlObj instanceof  SQLGenericOperator) {
0729:                    SQLGenericOperator op = (SQLGenericOperator) sqlObj;
0730:                    for (Iterator iter = op.getInputObjectMap().values()
0731:                            .iterator(); iter.hasNext();) {
0732:                        SQLInputObject inputWrapper = (SQLInputObject) iter
0733:                                .next();
0734:                        SQLObject wrappedObj = inputWrapper.getSQLObject();
0735:                        return getFirstSourceColumnReferencedIn(wrappedObj);
0736:                    }
0737:                }
0738:
0739:                return null;
0740:            }
0741:
0742:            private boolean isObjectMappedToExpression(SQLObject obj,
0743:                    List expObjects) {
0744:                boolean result = false;
0745:                Iterator it = expObjects.iterator();
0746:
0747:                while (it.hasNext()) {
0748:                    SQLConnectableObject expObj = (SQLConnectableObject) it
0749:                            .next();
0750:                    result = SQLObjectUtil.isObjectMappedToExpression(obj,
0751:                            expObj);
0752:                    if (result) {
0753:                        return result;
0754:                    }
0755:                }
0756:
0757:                return result;
0758:            }
0759:
0760:            /**
0761:             * Indicates whether the given String represents a valid operator for a join
0762:             * predicate.
0763:             *
0764:             * @param op String representing operator to be tested
0765:             * @return true if join operator is valid, false otherwise
0766:             */
0767:            private boolean isValidJoinOperator(String op) {
0768:                // We currently only support equijoins.
0769:                return op != null && op.trim().equalsIgnoreCase("=");
0770:            }
0771:
0772:            private void validate(Collection allObjects, List expObjects) {
0773:                Iterator it = allObjects.iterator();
0774:                SQLObject sqlObject = null;
0775:                SQLObject column = null;
0776:                SQLConnectableObject exprObj = null;
0777:                String desc = null;
0778:                while (it.hasNext()) {
0779:                    sqlObject = (SQLObject) it.next();
0780:
0781:                    if (sqlObject.getObjectType() == SQLConstants.COLUMN_REF) {
0782:                        column = ((ColumnRef) sqlObject).getColumn();
0783:
0784:                        if ((column.getObjectType() == SQLConstants.SOURCE_COLUMN)
0785:                                && !(((SQLDBColumn) column).isVisible())) {
0786:                            String nbBundle9 = mLoc
0787:                                    .t(
0788:                                            "PRSR001: Column {0} used in a condition is not visible.",
0789:                                            sqlObject.getDisplayName());
0790:                            desc = Localizer.parse(nbBundle9);
0791:                            ValidationInfo validationInfo = new ValidationInfoImpl(
0792:                                    sqlObject.getParentObject(), desc,
0793:                                    ValidationInfo.VALIDATION_ERROR);
0794:                            validationInfoList.add(validationInfo);
0795:                        }
0796:                    }
0797:
0798:                    if (sqlObject instanceof  SQLConnectableObject) {
0799:                        exprObj = (SQLConnectableObject) sqlObject;
0800:                        SQLValidationVisitor vVisitor = new SQLValidationVisitor();
0801:                        vVisitor.visitExpression(exprObj, false);
0802:                        List<ValidationInfo> vInfos = vVisitor
0803:                                .getValidationInfoList();
0804:                        if (vInfos.size() > 0) {
0805:                            validationInfoList.addAll(vInfos);
0806:                        }
0807:                    } else if (!isObjectMappedToExpression(sqlObject,
0808:                            expObjects)) {
0809:                        String nbBundle10 = mLoc.t(
0810:                                "PRSR001: {0} is not mapped to an expression.",
0811:                                new Object[] { sqlObject.getDisplayName() });
0812:                        desc = Localizer.parse(nbBundle10);
0813:                        ValidationInfo validationInfo = new ValidationInfoImpl(
0814:                                sqlObject, desc,
0815:                                ValidationInfo.VALIDATION_ERROR);
0816:
0817:                        validationInfoList.add(validationInfo);
0818:                    }
0819:                }
0820:            }
0821:
0822:            /**
0823:             * @param sqlObj
0824:             * @return
0825:             */
0826:            private ValidationInfoImpl validateDateFormatInput(
0827:                    SQLConnectableObject op, String argName, SQLObject sqlObj) {
0828:                ValidationInfoImpl errorInfo = null;
0829:                int validationType = ValidationInfo.VALIDATION_ERROR;
0830:
0831:                if (sqlObj instanceof  SQLLiteral) {
0832:                    SQLLiteral literal = (SQLLiteral) sqlObj;
0833:                    String value = literal.getValue();
0834:                    AxionDateTimeFormatParser formatParser = new AxionDateTimeFormatParser();
0835:
0836:                    try {
0837:                        formatParser.parseDateTimeFormatToJava(value);
0838:                    } catch (AxionException e) {
0839:                        String message = buildErrorMessageWithObjectIdentifiers(
0840:                                op.getDisplayName(),
0841:                                "ERROR_dateformat_invalid",
0842:                                new Object[] { value });
0843:                        errorInfo = new ValidationInfoImpl(op, message,
0844:                                validationType);
0845:                    }
0846:                }
0847:
0848:                return errorInfo;
0849:            }
0850:
0851:            private void validateExpressionObjectChildren(
0852:                    SQLConnectableObject exp) {
0853:                // go through children of this expression object
0854:                List childList = exp.getChildSQLObjects();
0855:                Iterator it = childList.iterator();
0856:
0857:                while (it.hasNext()) {
0858:                    SQLObject sqlObject = (SQLObject) it.next();
0859:                    SQLConnectableObject exprObj = null;
0860:                    if (sqlObject instanceof  SQLConnectableObject) {
0861:                        exprObj = (SQLConnectableObject) sqlObject;
0862:                        visitExpression(exprObj, true);
0863:                    }
0864:                }
0865:            }
0866:
0867:            private void validateGroupBy(TargetTable targetTable, int stmtType) {
0868:                if (targetTable.getSQLGroupBy() != null
0869:                        && !targetTable.getSQLGroupBy().getColumns().isEmpty()) {
0870:                    switch (stmtType) {
0871:                    case SQLConstants.INSERT_STATEMENT:
0872:                        break;
0873:                    default:
0874:                        ValidationInfo validationInfo = new ValidationInfoImpl(
0875:                                targetTable,
0876:                                "Defined GroupBy/Having clause will not be used :: "
0877:                                        + targetTable.getSQLGroupBy()
0878:                                                .toString(),
0879:                                ValidationInfo.VALIDATION_WARNING);
0880:                        validationInfoList.add(validationInfo);
0881:                    }
0882:                }
0883:
0884:                // validate group by columns
0885:                SQLGroupBy groupBy = targetTable.getSQLGroupBy();
0886:                List groupByNodes = groupBy != null ? groupBy.getColumns()
0887:                        : null;
0888:                SQLGroupByValidationVisitor groupByVisitor = new SQLGroupByValidationVisitor(
0889:                        targetTable, groupByNodes);
0890:                groupByVisitor.visit(targetTable.getMappedColumns());
0891:                validationInfoList.addAll(groupByVisitor
0892:                        .getValidationInfoList());
0893:
0894:                if (groupBy != null) {
0895:                    // validate having condition
0896:                    SQLCondition having = groupBy.getHavingCondition();
0897:                    if (having != null) {
0898:                        if (!having.isValid()) {
0899:                            String desc = buildErrorMessageWithObjectIdentifier(
0900:                                    having.getDisplayName(),
0901:                                    "ERROR_condition_invalid");
0902:                            ValidationInfo validationInfo = new ValidationInfoImpl(
0903:                                    having, desc,
0904:                                    ValidationInfo.VALIDATION_ERROR);
0905:                            validationInfoList.add(validationInfo);
0906:                        } else {
0907:                            visit(having);
0908:                        }
0909:
0910:                        groupByVisitor.reset();
0911:                        groupByVisitor.visit(Collections.singletonList(having
0912:                                .getRootPredicate()));
0913:                        validationInfoList.addAll(groupByVisitor
0914:                                .getValidationInfoList());
0915:                    }
0916:
0917:                    // validate: selected target column as group by node/expr should be mapped
0918:                    // validate: Selected target column should not be mapped to aggregate function
0919:                    for (Iterator iter = groupByNodes.iterator(); iter
0920:                            .hasNext();) {
0921:                        SQLObject sqlObj = (SQLObject) iter.next();
0922:                        if (sqlObj instanceof  TargetColumn) {
0923:                            TargetColumn col = (TargetColumn) sqlObj;
0924:                            if (col.getValue() == null) {
0925:                                ValidationInfoImpl validationInfo = new ValidationInfoImpl(
0926:                                        targetTable,
0927:                                        "Selected group by target coulmn not mapped: "
0928:                                                + col,
0929:                                        ValidationInfo.VALIDATION_ERROR);
0930:                                validationInfoList.add(validationInfo);
0931:                            } else if (SQLObjectUtil
0932:                                    .isAggregateFunctionMapped(col.getValue())) {
0933:                                ValidationInfoImpl validationInfo = new ValidationInfoImpl(
0934:                                        targetTable,
0935:                                        "Group By clause can't contain agrregate function: "
0936:                                                + col + "->" + col.getValue(),
0937:                                        ValidationInfo.VALIDATION_ERROR);
0938:                                validationInfoList.add(validationInfo);
0939:                            }
0940:                        }
0941:                    }
0942:                }
0943:            }
0944:
0945:            /**
0946:             * Validates whether the given SQLInputObject is an appropriate input for the argument
0947:             * as referenced by the given String for the given SQLConnectableObject.
0948:             *
0949:             * @param op SQLConnectableObject whose input as referenced by <code>argName</code>
0950:             *        is to be validated
0951:             * @param argName name of input argument to be validated
0952:             * @param displayName display name of input argument
0953:             * @param obj SQLObject representing input to be validated
0954:             * @return ExpressionValidationInfo instance if an error or warning has been
0955:             *         generated; null otherwise.
0956:             */
0957:            private ValidationInfoImpl validateInputDataType(
0958:                    SQLConnectableObject op, String argName,
0959:                    String displayName, SQLObject sqlObj) {
0960:                final String identifier = op.getDisplayName();
0961:
0962:                ValidationInfoImpl expValidationInfo = null;
0963:                String desc = null;
0964:                int validationType = ValidationInfo.VALIDATION_ERROR;
0965:
0966:                int compatibility = op.isInputCompatible(argName, sqlObj);
0967:                switch (compatibility) {
0968:                case SQLConstants.TYPE_CHECK_INCOMPATIBLE:
0969:                    desc = buildErrorMessageWithObjectIdentifiers(identifier,
0970:                            "ERROR_datatype_incompatible",
0971:                            new Object[] { displayName });
0972:                    break;
0973:                case SQLConstants.TYPE_CHECK_DOWNCAST_WARNING:
0974:                case SQLConstants.TYPE_CHECK_UNKNOWN:
0975:                    String datatype = SQLUtils.getStdSqlType(sqlObj
0976:                            .getJdbcType());
0977:                    if (datatype == null) {
0978:                        datatype = "unknown";
0979:                    }
0980:                    desc = buildErrorMessageWithObjectIdentifiers(identifier,
0981:                            "WARNING_datatype_downcast_unknown", new Object[] {
0982:                                    datatype, displayName });
0983:                    validationType = ValidationInfo.VALIDATION_WARNING;
0984:                    break;
0985:                case SQLConstants.TYPE_CHECK_COMPATIBLE:
0986:                case SQLConstants.TYPE_CHECK_SAME:
0987:                default:
0988:                    desc = null;
0989:                }
0990:
0991:                if (desc != null) {
0992:                    expValidationInfo = new ValidationInfoImpl(op, desc,
0993:                            validationType);
0994:                } else if (sqlObj instanceof  SQLCastOperator
0995:                        && op instanceof  TargetTable) {
0996:                    SQLCastOperator castOp = (SQLCastOperator) sqlObj;
0997:                    TargetTable target = (TargetTable) op;
0998:
0999:                    DBColumn col = target.getColumn(argName);
1000:                    int colPrecision = (col != null) ? col.getPrecision() : 0;
1001:                    int castPrecision = castOp.getPrecision();
1002:
1003:                    int colType = (col != null) ? col.getJdbcType()
1004:                            : SQLConstants.JDBCSQL_TYPE_UNDEFINED;
1005:                    switch (colType) {
1006:                    case Types.VARCHAR:
1007:                    case Types.CHAR:
1008:                    case Types.NUMERIC:
1009:                        if (castPrecision > colPrecision) {
1010:                            String castError = buildErrorMessageWithObjectIdentifiers(
1011:                                    identifier,
1012:                                    "ERROR_datatype_castexceedsprecision",
1013:                                    new Object[] { new Integer(castPrecision),
1014:                                            displayName,
1015:                                            new Integer(colPrecision) });
1016:                            expValidationInfo = new ValidationInfoImpl(castOp,
1017:                                    castError, validationType);
1018:                        }
1019:                        break;
1020:                    default:
1021:                        break;
1022:                    }
1023:                }
1024:
1025:                return expValidationInfo;
1026:            }
1027:
1028:            private void validateSourceTableCondition(TargetTable targetTable) {
1029:                try {
1030:                    // do source table extraction condition validation
1031:                    Iterator sIt = targetTable.getSourceTableList().iterator();
1032:                    while (sIt.hasNext()) {
1033:                        SourceTable sTable = (SourceTable) sIt.next();
1034:                        sTable.visit(this );
1035:                    }
1036:                } catch (BaseException ex) {
1037:                    mLogger
1038:                            .errorNoloc(
1039:                                    mLoc
1040:                                            .t(
1041:                                                    "PRSR132: Could not find source tables for this target table{0}in {1}",
1042:                                                    targetTable.getName(),
1043:                                                    SQLValidationVisitor.class
1044:                                                            .getName()), ex);
1045:                }
1046:            }
1047:
1048:            private void validateTargetConditionForTargetColumnUsage(
1049:                    SQLCondition condition) {
1050:                try {
1051:                    SQLPredicate predicate = condition.getRootPredicate();
1052:
1053:                    if (predicate != null) {
1054:                        if (!predicate.hasTargetColumn()) {
1055:                            String nbBundle11 = mLoc
1056:                                    .t("PRSR001: Target/Join condition should have at least one target table column.");
1057:                            String desc = Localizer.parse(nbBundle11);
1058:                            ValidationInfoImpl validationInfo = new ValidationInfoImpl(
1059:                                    condition, desc,
1060:                                    ValidationInfo.VALIDATION_ERROR);
1061:                            validationInfoList.add(validationInfo);
1062:                        }
1063:                    }
1064:                } catch (Exception ex) {
1065:                    mLogger.errorNoloc(mLoc.t(
1066:                            "PRSR133: Validating target table condition in{0}",
1067:                            SQLValidationVisitor.class.getName()), ex);
1068:                }
1069:            }
1070:
1071:            private void validateTargetTableCondition(TargetTable targetTable,
1072:                    final String identifier, int stmtType) {
1073:                switch (stmtType) {
1074:                case SQLConstants.INSERT_UPDATE_STATEMENT:
1075:                case SQLConstants.UPDATE_STATEMENT:
1076:                    SQLCondition cond = targetTable.getJoinCondition();
1077:                    SQLPredicate rootP = null;
1078:                    if (cond != null) {
1079:                        rootP = cond.getRootPredicate();
1080:                    }
1081:
1082:                    if (rootP == null) {
1083:                        String desc = null;
1084:
1085:                        if (stmtType == SQLConstants.INSERT_UPDATE_STATEMENT) {
1086:                            desc = buildErrorMessageWithObjectIdentifier(
1087:                                    identifier, "ERROR_mergecondition_missing");
1088:                        } else {
1089:                            try {
1090:                                // If this is a static update (no associated source tables), a
1091:                                // condition is not required.
1092:                                if (targetTable.getSourceTableList().size() == 0) {
1093:                                    break;
1094:                                }
1095:                                desc = buildErrorMessageWithObjectIdentifier(
1096:                                        identifier,
1097:                                        "ERROR_updatecondition_missing");
1098:                            } catch (BaseException ignore) {
1099:                                break;
1100:                            }
1101:                        }
1102:
1103:                        if (desc != null) {
1104:                            ValidationInfoImpl validationInfo = new ValidationInfoImpl(
1105:                                    targetTable, desc,
1106:                                    ValidationInfo.VALIDATION_ERROR);
1107:                            validationInfoList.add(validationInfo);
1108:                        }
1109:                    }
1110:                    break;
1111:                default:
1112:                    break;
1113:                }
1114:
1115:                // do target table condition validation
1116:                SQLCondition joinCondition = targetTable.getJoinCondition();
1117:                if (joinCondition != null) {
1118:                    if (!joinCondition.isValid()) {
1119:                        String desc = buildErrorMessageWithObjectIdentifier(
1120:                                identifier, "ERROR_condition_invalid");
1121:                        ValidationInfoImpl validationInfo = new ValidationInfoImpl(
1122:                                joinCondition, desc,
1123:                                ValidationInfo.VALIDATION_ERROR);
1124:                        validationInfoList.add(validationInfo);
1125:                    } else {
1126:                        validateTargetConditionForTargetColumnUsage(joinCondition);
1127:                    }
1128:                }
1129:
1130:                // do target table filter condition validation
1131:                SQLCondition filterCondition = targetTable.getFilterCondition();
1132:                if (filterCondition != null) {
1133:                    if (!filterCondition.isValid()) {
1134:                        String desc = buildErrorMessageWithObjectIdentifier(
1135:                                identifier, "ERROR_condition_invalid");
1136:                        ValidationInfoImpl validationInfo = new ValidationInfoImpl(
1137:                                filterCondition, desc,
1138:                                ValidationInfo.VALIDATION_ERROR);
1139:                        validationInfoList.add(validationInfo);
1140:                    }
1141:                }
1142:            }
1143:
1144:            private void visitExpression(SQLConnectableObject operator,
1145:                    boolean recurse) {
1146:                final String identifier = operator.getDisplayName();
1147:
1148:                Iterator iter = operator.getInputObjectMap().entrySet()
1149:                        .iterator();
1150:                while (iter.hasNext()) {
1151:                    Map.Entry entry = (Map.Entry) iter.next();
1152:                    String argName = (String) entry.getKey();
1153:                    SQLInputObject obj = (SQLInputObject) entry.getValue();
1154:                    ValidationInfo expValidationInfo = null;
1155:
1156:                    if (obj == null) {
1157:                        String desc = buildErrorMessageWithObjectIdentifiers(
1158:                                identifier, "ERROR_object_not_linked",
1159:                                new Object[] { obj.getDisplayName() });
1160:                        expValidationInfo = new ValidationInfoImpl(operator,
1161:                                desc, ValidationInfo.VALIDATION_ERROR);
1162:                    }
1163:
1164:                    SQLObject sqlObj = obj.getSQLObject();
1165:                    if (sqlObj == null) {
1166:                        String desc = buildErrorMessageWithObjectIdentifiers(
1167:                                identifier, "ERROR_object_not_linked",
1168:                                new Object[] { obj.getDisplayName() });
1169:                        expValidationInfo = new ValidationInfoImpl(operator,
1170:                                desc, ValidationInfo.VALIDATION_ERROR);
1171:                    } else {
1172:                        expValidationInfo = (sqlObj instanceof  SQLCustomOperatorImpl) ? null
1173:                                : validateInputDataType(operator, argName, obj
1174:                                        .getDisplayName(), sqlObj);
1175:                    }
1176:
1177:                    if (expValidationInfo != null) {
1178:                        validationInfoList.add(expValidationInfo);
1179:                    }
1180:
1181:                    if (sqlObj != null
1182:                            && operator.isInputStatic(argName)
1183:                            && DATE_FORMAT_OPS.contains(identifier
1184:                                    .toLowerCase())) {
1185:                        if ("format".equals(argName.toLowerCase())
1186:                                || "right".equals(argName.toLowerCase())) {
1187:                            expValidationInfo = validateDateFormatInput(
1188:                                    operator, argName, sqlObj);
1189:                            if (expValidationInfo != null) {
1190:                                validationInfoList.add(expValidationInfo);
1191:                            }
1192:                        }
1193:                    }
1194:
1195:                    if (recurse && sqlObj != null
1196:                            && sqlObj instanceof  SQLConnectableObject) {
1197:                        SQLConnectableObject inObj = (SQLConnectableObject) sqlObj;
1198:                        inObj.visit(this );
1199:                    }
1200:                }
1201:
1202:                // validate children
1203:                validateExpressionObjectChildren(operator);
1204:            }
1205:        }
ww__w__.___j___av__a__2__s__.__c_o_m_ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.