Search in sources :

Example 1 with UtilTimer

use of org.apache.ofbiz.base.util.UtilTimer in project ofbiz-framework by apache.

the class ModelServiceReader method getModelServices.

private Map<String, ModelService> getModelServices() {
    UtilTimer utilTimer = new UtilTimer();
    Document document;
    if (this.isFromURL) {
        document = getDocument(readerURL);
        if (document == null) {
            return null;
        }
    } else {
        try {
            document = handler.getDocument();
        } catch (GenericConfigException e) {
            Debug.logError(e, "Error getting XML document from resource", module);
            return null;
        }
    }
    Map<String, ModelService> modelServices = new HashMap<>();
    Element docElement = document.getDocumentElement();
    if (docElement == null) {
        return null;
    }
    docElement.normalize();
    String resourceLocation = handler.getLocation();
    try {
        resourceLocation = handler.getURL().toExternalForm();
    } catch (GenericConfigException e) {
        Debug.logError(e, "Could not get resource URL", module);
    }
    int i = 0;
    Node curChild = docElement.getFirstChild();
    if (curChild != null) {
        if (this.isFromURL) {
            utilTimer.timerString("Before start of service loop in file " + readerURL);
        } else {
            utilTimer.timerString("Before start of service loop in " + handler);
        }
        do {
            if (curChild.getNodeType() == Node.ELEMENT_NODE && "service".equals(curChild.getNodeName())) {
                i++;
                Element curServiceElement = (Element) curChild;
                String serviceName = UtilXml.checkEmpty(curServiceElement.getAttribute("name"));
                // check to see if service with same name has already been read
                if (modelServices.containsKey(serviceName)) {
                    Debug.logWarning("Service " + serviceName + " is defined more than once, " + "most recent will over-write previous definition(s)", module);
                }
                ModelService service = createModelService(curServiceElement, resourceLocation);
                modelServices.put(serviceName, service);
            }
        } while ((curChild = curChild.getNextSibling()) != null);
    } else {
        Debug.logWarning("No child nodes found.", module);
    }
    if (this.isFromURL) {
        utilTimer.timerString("Finished file " + readerURL + " - Total Services: " + i + " FINISHED");
        Debug.logInfo("Loaded [" + i + "] Services from " + readerURL, module);
    } else {
        utilTimer.timerString("Finished document in " + handler + " - Total Services: " + i + " FINISHED");
        Debug.logInfo("Loaded [" + i + "] Services from " + resourceLocation, module);
    }
    return modelServices;
}
Also used : GenericConfigException(org.apache.ofbiz.base.config.GenericConfigException) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Element(org.w3c.dom.Element) Node(org.w3c.dom.Node) UtilTimer(org.apache.ofbiz.base.util.UtilTimer) Document(org.w3c.dom.Document)

Example 2 with UtilTimer

use of org.apache.ofbiz.base.util.UtilTimer in project ofbiz-framework by apache.

the class DatabaseUtil method checkDb.

public void checkDb(Map<String, ModelEntity> modelEntities, List<String> colWrongSize, List<String> messages, boolean checkPks, boolean checkFks, boolean checkFkIdx, boolean addMissing) {
    if (isLegacy) {
        throw new RuntimeException("Cannot run checkDb on a legacy database connection; configure a database helper (entityengine.xml)");
    }
    ExecutorService executor = Executors.newFixedThreadPool(datasourceInfo.getMaxWorkerPoolSize());
    UtilTimer timer = new UtilTimer();
    timer.timerString("Start - Before Get Database Meta Data");
    // get ALL tables from this database
    TreeSet<String> tableNames = this.getTableNames(messages);
    TreeSet<String> fkTableNames = tableNames == null ? null : new TreeSet<String>(tableNames);
    TreeSet<String> indexTableNames = tableNames == null ? null : new TreeSet<String>(tableNames);
    if (tableNames == null) {
        String message = "Could not get table name information from the database, aborting.";
        if (messages != null)
            messages.add(message);
        Debug.logError(message, module);
        return;
    }
    timer.timerString("After Get All Table Names");
    // get ALL column info, put into hashmap by table name
    Map<String, Map<String, ColumnCheckInfo>> colInfo = getColumnInfo(tableNames, checkPks, messages, executor);
    if (colInfo == null) {
        String message = "Could not get column information from the database, aborting.";
        if (messages != null)
            messages.add(message);
        Debug.logError(message, module);
        return;
    }
    timer.timerString("After Get All Column Info");
    // -make sure all entities have a corresponding table
    // -list all tables that do not have a corresponding entity
    // -display message if number of table columns does not match number of entity fields
    // -list all columns that do not have a corresponding field
    // -make sure each corresponding column is of the correct type
    // -list all fields that do not have a corresponding column
    timer.timerString("Before Individual Table/Column Check");
    List<ModelEntity> modelEntityList = new ArrayList<ModelEntity>(modelEntities.values());
    // sort using compareTo method on ModelEntity
    Collections.sort(modelEntityList);
    int curEnt = 0;
    int totalEnt = modelEntityList.size();
    List<ModelEntity> entitiesAdded = new LinkedList<ModelEntity>();
    String schemaName;
    try {
        schemaName = getSchemaName(messages);
    } catch (SQLException e) {
        String message = "Could not get schema name the database, aborting.";
        if (messages != null)
            messages.add(message);
        Debug.logError(message, module);
        return;
    }
    List<Future<CreateTableCallable>> tableFutures = new LinkedList<Future<CreateTableCallable>>();
    for (ModelEntity entity : modelEntityList) {
        curEnt++;
        // if this is a view entity, do not check it...
        if (entity instanceof ModelViewEntity) {
            String entMessage = "(" + timer.timeSinceLast() + "ms) NOT Checking #" + curEnt + "/" + totalEnt + " View Entity " + entity.getEntityName();
            Debug.logVerbose(entMessage, module);
            if (messages != null)
                messages.add(entMessage);
            continue;
        // if never-check is set then don't check it either
        } else if (entity.getNeverCheck()) {
            String entMessage = "(" + timer.timeSinceLast() + "ms) NOT Checking #" + curEnt + "/" + totalEnt + " Entity " + entity.getEntityName();
            Debug.logVerbose(entMessage, module);
            if (messages != null)
                messages.add(entMessage);
            continue;
        }
        String plainTableName = entity.getPlainTableName();
        String tableName;
        if (UtilValidate.isNotEmpty(schemaName)) {
            tableName = schemaName + "." + plainTableName;
        } else {
            tableName = plainTableName;
        }
        String entMessage = "(" + timer.timeSinceLast() + "ms) Checking #" + curEnt + "/" + totalEnt + " Entity " + entity.getEntityName() + " with table " + tableName;
        Debug.logVerbose(entMessage, module);
        if (messages != null)
            messages.add(entMessage);
        // -make sure all entities have a corresponding table
        if (tableNames.contains(tableName)) {
            tableNames.remove(tableName);
            if (colInfo != null) {
                Map<String, ModelField> fieldColNames = new HashMap<String, ModelField>();
                Iterator<ModelField> fieldIter = entity.getFieldsIterator();
                while (fieldIter.hasNext()) {
                    ModelField field = fieldIter.next();
                    fieldColNames.put(field.getColName(), field);
                }
                Map<String, ColumnCheckInfo> colMap = colInfo.get(tableName);
                if (colMap != null) {
                    for (ColumnCheckInfo ccInfo : colMap.values()) {
                        // -list all columns that do not have a corresponding field
                        if (fieldColNames.containsKey(ccInfo.columnName)) {
                            ModelField field = null;
                            field = fieldColNames.remove(ccInfo.columnName);
                            ModelFieldType modelFieldType = modelFieldTypeReader.getModelFieldType(field.getType());
                            if (modelFieldType != null) {
                                // make sure each corresponding column is of the correct type
                                String fullTypeStr = modelFieldType.getSqlType();
                                String typeName;
                                int columnSize = -1;
                                int decimalDigits = -1;
                                int openParen = fullTypeStr.indexOf('(');
                                int closeParen = fullTypeStr.indexOf(')');
                                int comma = fullTypeStr.indexOf(',');
                                if (openParen > 0 && closeParen > 0 && closeParen > openParen) {
                                    typeName = fullTypeStr.substring(0, openParen);
                                    if (!("DATETIME".equals(typeName) || "TIME".equals(typeName))) {
                                        // for DATETIME and TIME fields the number within the parenthesis doesn't represent the column size
                                        if (comma > 0 && comma > openParen && comma < closeParen) {
                                            String csStr = fullTypeStr.substring(openParen + 1, comma);
                                            try {
                                                columnSize = Integer.parseInt(csStr);
                                            } catch (NumberFormatException e) {
                                                Debug.logError(e, module);
                                            }
                                            String ddStr = fullTypeStr.substring(comma + 1, closeParen);
                                            try {
                                                decimalDigits = Integer.parseInt(ddStr);
                                            } catch (NumberFormatException e) {
                                                Debug.logError(e, module);
                                            }
                                        } else if (openParen + 1 < closeParen) {
                                            String csStr = fullTypeStr.substring(openParen + 1, closeParen);
                                            try {
                                                columnSize = Integer.parseInt(csStr);
                                            } catch (NumberFormatException e) {
                                                Debug.logError(e, module);
                                            }
                                        }
                                    }
                                } else {
                                    typeName = fullTypeStr;
                                }
                                // override the default typeName with the sqlTypeAlias if it is specified
                                if (UtilValidate.isNotEmpty(modelFieldType.getSqlTypeAlias())) {
                                    typeName = modelFieldType.getSqlTypeAlias();
                                }
                                // NOTE: this may need a toUpperCase in some cases, keep an eye on it, okay just compare with ignore case
                                if (!ccInfo.typeName.equalsIgnoreCase(typeName)) {
                                    String message = "Column [" + ccInfo.columnName + "] of table [" + tableName + "] of entity [" + entity.getEntityName() + "] is of type [" + ccInfo.typeName + "] in the database, but is defined as type [" + typeName + "] in the entity definition.";
                                    Debug.logError(message, module);
                                    if (messages != null)
                                        messages.add(message);
                                }
                                if (columnSize != -1 && ccInfo.columnSize != -1 && columnSize != ccInfo.columnSize && (columnSize * 3) != ccInfo.columnSize) {
                                    String message = "Column [" + ccInfo.columnName + "] of table [" + tableName + "] of entity [" + entity.getEntityName() + "] has a column size of [" + ccInfo.columnSize + "] in the database, but is defined to have a column size of [" + columnSize + "] in the entity definition.";
                                    Debug.logWarning(message, module);
                                    if (messages != null)
                                        messages.add(message);
                                    if (columnSize > ccInfo.columnSize && colWrongSize != null) {
                                        // add item to list of wrong sized columns; only if the entity is larger
                                        colWrongSize.add(entity.getEntityName() + "." + field.getName());
                                    }
                                }
                                if (decimalDigits != -1 && decimalDigits != ccInfo.decimalDigits) {
                                    String message = "Column [" + ccInfo.columnName + "] of table [" + tableName + "] of entity [" + entity.getEntityName() + "] has a decimalDigits of [" + ccInfo.decimalDigits + "] in the database, but is defined to have a decimalDigits of [" + decimalDigits + "] in the entity definition.";
                                    Debug.logWarning(message, module);
                                    if (messages != null)
                                        messages.add(message);
                                }
                                // do primary key matching check
                                if (checkPks && ccInfo.isPk && !field.getIsPk()) {
                                    String message = "Column [" + ccInfo.columnName + "] of table [" + tableName + "] of entity [" + entity.getEntityName() + "] IS a primary key in the database, but IS NOT a primary key in the entity definition. The primary key for this table needs to be re-created or modified so that this column is NOT part of the primary key.";
                                    Debug.logError(message, module);
                                    if (messages != null)
                                        messages.add(message);
                                }
                                if (checkPks && !ccInfo.isPk && field.getIsPk()) {
                                    String message = "Column [" + ccInfo.columnName + "] of table [" + tableName + "] of entity [" + entity.getEntityName() + "] IS NOT a primary key in the database, but IS a primary key in the entity definition. The primary key for this table needs to be re-created or modified to add this column to the primary key. Note that data may need to be added first as a primary key column cannot have an null values.";
                                    Debug.logError(message, module);
                                    if (messages != null)
                                        messages.add(message);
                                }
                            } else {
                                String message = "Column [" + ccInfo.columnName + "] of table [" + tableName + "] of entity [" + entity.getEntityName() + "] has a field type name of [" + field.getType() + "] which is not found in the field type definitions";
                                Debug.logError(message, module);
                                if (messages != null)
                                    messages.add(message);
                            }
                        } else {
                            String message = "Column [" + ccInfo.columnName + "] of table [" + tableName + "] of entity [" + entity.getEntityName() + "] exists in the database but has no corresponding field" + ((checkPks && ccInfo.isPk) ? " (and it is a PRIMARY KEY COLUMN)" : "");
                            Debug.logWarning(message, module);
                            if (messages != null)
                                messages.add(message);
                        }
                    }
                    // -display message if number of table columns does not match number of entity fields
                    if (colMap.size() != entity.getFieldsSize()) {
                        String message = "Entity [" + entity.getEntityName() + "] has " + entity.getFieldsSize() + " fields but table [" + tableName + "] has " + colMap.size() + " columns.";
                        Debug.logWarning(message, module);
                        if (messages != null)
                            messages.add(message);
                    }
                }
                // -list all fields that do not have a corresponding column
                for (ModelField field : fieldColNames.values()) {
                    String message = "Field [" + field.getName() + "] of entity [" + entity.getEntityName() + "] is missing its corresponding column [" + field.getColName() + "]" + (field.getIsPk() ? " (and it is a PRIMARY KEY FIELD)" : "");
                    Debug.logWarning(message, module);
                    if (messages != null)
                        messages.add(message);
                    if (addMissing) {
                        // add the column
                        String errMsg = addColumn(entity, field);
                        if (UtilValidate.isNotEmpty(errMsg)) {
                            message = "Could not add column [" + field.getColName() + "] to table [" + tableName + "]: " + errMsg;
                            Debug.logError(message, module);
                            if (messages != null)
                                messages.add(message);
                        } else {
                            message = "Added column [" + field.getColName() + "] to table [" + tableName + "]" + (field.getIsPk() ? " (NOTE: this is a PRIMARY KEY FIELD, but the primary key was not updated automatically (not considered a safe operation), be sure to fill in any needed data and re-create the primary key)" : "");
                            Debug.logImportant(message, module);
                            if (messages != null)
                                messages.add(message);
                        }
                    }
                }
            }
        } else {
            String message = "Entity [" + entity.getEntityName() + "] has no table in the database";
            Debug.logWarning(message, module);
            if (messages != null)
                messages.add(message);
            if (addMissing) {
                // create the table
                tableFutures.add(executor.submit(new CreateTableCallable(entity, modelEntities, tableName)));
            }
        }
    }
    for (CreateTableCallable tableCallable : ExecutionPool.getAllFutures(tableFutures)) {
        tableCallable.updateData(messages, entitiesAdded);
    }
    timer.timerString("After Individual Table/Column Check");
    // -list all tables that do not have a corresponding entity
    for (String tableName : tableNames) {
        String message = "Table named [" + tableName + "] exists in the database but has no corresponding entity";
        Debug.logWarning(message, module);
        if (messages != null)
            messages.add(message);
    }
    // for each newly added table, add fk indices
    if (datasourceInfo.getUseForeignKeyIndices()) {
        int totalFkIndices = 0;
        List<Future<AbstractCountingCallable>> fkIndicesFutures = new LinkedList<Future<AbstractCountingCallable>>();
        for (ModelEntity curEntity : entitiesAdded) {
            if (curEntity.getRelationsOneSize() > 0) {
                fkIndicesFutures.add(executor.submit(new AbstractCountingCallable(curEntity, modelEntities) {

                    public AbstractCountingCallable call() throws Exception {
                        count = createForeignKeyIndices(entity, datasourceInfo.getConstraintNameClipLength(), messages);
                        return this;
                    }
                }));
            }
        }
        for (AbstractCountingCallable fkIndicesCallable : ExecutionPool.getAllFutures(fkIndicesFutures)) {
            totalFkIndices += fkIndicesCallable.updateData(messages);
        }
        if (totalFkIndices > 0)
            Debug.logImportant("==== TOTAL Foreign Key Indices Created: " + totalFkIndices, module);
    }
    // for each newly added table, add fks
    if (datasourceInfo.getUseForeignKeys()) {
        int totalFks = 0;
        for (ModelEntity curEntity : entitiesAdded) {
            totalFks += this.createForeignKeys(curEntity, modelEntities, datasourceInfo.getConstraintNameClipLength(), datasourceInfo.getFkStyle(), datasourceInfo.getUseFkInitiallyDeferred(), messages);
        }
        if (totalFks > 0)
            Debug.logImportant("==== TOTAL Foreign Keys Created: " + totalFks, module);
    }
    // for each newly added table, add declared indexes
    if (datasourceInfo.getUseIndices()) {
        int totalDis = 0;
        List<Future<AbstractCountingCallable>> disFutures = new LinkedList<Future<AbstractCountingCallable>>();
        for (ModelEntity curEntity : entitiesAdded) {
            if (curEntity.getIndexesSize() > 0) {
                disFutures.add(executor.submit(new AbstractCountingCallable(curEntity, modelEntities) {

                    public AbstractCountingCallable call() throws Exception {
                        count = createDeclaredIndices(entity, messages);
                        return this;
                    }
                }));
            }
        }
        for (AbstractCountingCallable disCallable : ExecutionPool.getAllFutures(disFutures)) {
            totalDis += disCallable.updateData(messages);
        }
        if (totalDis > 0)
            Debug.logImportant("==== TOTAL Declared Indices Created: " + totalDis, module);
    }
    // make sure each one-relation has an FK
    if (checkFks) {
        // if (!justColumns && datasourceInfo.getUseForeignKeys() && datasourceInfo.checkForeignKeysOnStart) {
        // NOTE: This ISN'T working for Postgres or MySQL, who knows about others, may be from JDBC driver bugs...
        int numFksCreated = 0;
        // TODO: check each key-map to make sure it exists in the FK, if any differences warn and then remove FK and recreate it
        // get ALL column info, put into hashmap by table name
        Map<String, Map<String, ReferenceCheckInfo>> refTableInfoMap = this.getReferenceInfo(fkTableNames, messages);
        if (refTableInfoMap == null) {
            // uh oh, something happened while getting info...
            if (Debug.verboseOn())
                Debug.logVerbose("Ref Table Info Map is null", module);
        } else {
            for (ModelEntity entity : modelEntityList) {
                String entityName = entity.getEntityName();
                // if this is a view entity, do not check it...
                if (entity instanceof ModelViewEntity) {
                    String entMessage = "NOT Checking View Entity " + entity.getEntityName();
                    Debug.logVerbose(entMessage, module);
                    if (messages != null) {
                        messages.add(entMessage);
                    }
                    continue;
                }
                // get existing FK map for this table
                Map<String, ReferenceCheckInfo> rcInfoMap = refTableInfoMap.get(entity.getTableName(datasourceInfo));
                // Debug.logVerbose("Got ref info for table " + entity.getTableName(datasourceInfo) + ": " + rcInfoMap, module);
                // go through each relation to see if an FK already exists
                Iterator<ModelRelation> relations = entity.getRelationsIterator();
                boolean createdConstraints = false;
                while (relations.hasNext()) {
                    ModelRelation modelRelation = relations.next();
                    if (!"one".equals(modelRelation.getType())) {
                        continue;
                    }
                    ModelEntity relModelEntity = modelEntities.get(modelRelation.getRelEntityName());
                    if (relModelEntity == null) {
                        Debug.logError("No such relation: " + entity.getEntityName() + " -> " + modelRelation.getRelEntityName(), module);
                        continue;
                    }
                    String relConstraintName = makeFkConstraintName(modelRelation, datasourceInfo.getConstraintNameClipLength());
                    ReferenceCheckInfo rcInfo = null;
                    if (rcInfoMap != null) {
                        rcInfo = rcInfoMap.get(relConstraintName);
                    }
                    if (rcInfo != null) {
                        rcInfoMap.remove(relConstraintName);
                    } else {
                        // if not, create one
                        String noFkMessage = "No Foreign Key Constraint [" + relConstraintName + "] found for entity [" + entityName + "]";
                        if (messages != null)
                            messages.add(noFkMessage);
                        if (Debug.infoOn())
                            Debug.logInfo(noFkMessage, module);
                        if (addMissing) {
                            String errMsg = createForeignKey(entity, modelRelation, relModelEntity, datasourceInfo.getConstraintNameClipLength(), datasourceInfo.getFkStyle(), datasourceInfo.getUseFkInitiallyDeferred());
                            if (UtilValidate.isNotEmpty(errMsg)) {
                                String message = "Could not create foreign key " + relConstraintName + " for entity [" + entity.getEntityName() + "]: " + errMsg;
                                Debug.logError(message, module);
                                if (messages != null)
                                    messages.add(message);
                            } else {
                                String message = "Created foreign key " + relConstraintName + " for entity [" + entity.getEntityName() + "]";
                                Debug.logVerbose(message, module);
                                if (messages != null)
                                    messages.add(message);
                                createdConstraints = true;
                                numFksCreated++;
                            }
                        }
                    }
                }
                if (createdConstraints) {
                    String message = "Created foreign key(s) for entity [" + entity.getEntityName() + "]";
                    Debug.logImportant(message, module);
                    if (messages != null)
                        messages.add(message);
                }
                // show foreign key references that exist but are unknown
                if (rcInfoMap != null) {
                    for (String rcKeyLeft : rcInfoMap.keySet()) {
                        String message = "Unknown Foreign Key Constraint " + rcKeyLeft + " found in table " + entity.getTableName(datasourceInfo);
                        Debug.logImportant(message, module);
                        if (messages != null)
                            messages.add(message);
                    }
                }
            }
        }
        if (Debug.infoOn())
            Debug.logInfo("Created " + numFksCreated + " fk refs", module);
    }
    // make sure each one-relation has an index
    if (checkFkIdx || datasourceInfo.getCheckIndicesOnStart()) {
        // if (!justColumns && datasourceInfo.getUseForeignKeyIndices() && datasourceInfo.checkFkIndicesOnStart) {
        int numIndicesCreated = 0;
        // TODO: check each key-map to make sure it exists in the index, if any differences warn and then remove the index and recreate it
        // get ALL column info, put into hashmap by table name
        boolean[] needsUpperCase = new boolean[1];
        Map<String, Set<String>> tableIndexListMap = this.getIndexInfo(indexTableNames, messages, needsUpperCase);
        if (tableIndexListMap == null) {
            // uh oh, something happened while getting info...
            if (Debug.verboseOn())
                Debug.logVerbose("Ref Table Info Map is null", module);
        } else {
            for (ModelEntity entity : modelEntityList) {
                String entityName = entity.getEntityName();
                // if this is a view entity, do not check it...
                if (entity instanceof ModelViewEntity) {
                    String entMessage = "NOT Checking View Entity " + entity.getEntityName();
                    Debug.logVerbose(entMessage, module);
                    if (messages != null)
                        messages.add(entMessage);
                    continue;
                }
                // get existing index list for this table
                Set<String> tableIndexList = tableIndexListMap.get(entity.getTableName(datasourceInfo));
                if (tableIndexList == null) {
                    // evidently no indexes in the database for this table, do the create all
                    if (checkFkIdx) {
                        this.createForeignKeyIndices(entity, datasourceInfo.getConstraintNameClipLength(), messages);
                    }
                    if (datasourceInfo.getCheckIndicesOnStart()) {
                        this.createDeclaredIndices(entity, messages);
                    }
                    continue;
                }
                // go through each relation to see if an FK already exists
                boolean createdConstraints = false;
                Iterator<ModelRelation> relations = entity.getRelationsIterator();
                while (relations.hasNext()) {
                    ModelRelation modelRelation = relations.next();
                    if (!"one".equals(modelRelation.getType())) {
                        continue;
                    }
                    String relConstraintName = makeFkConstraintName(modelRelation, datasourceInfo.getConstraintNameClipLength());
                    if (tableIndexList.contains(relConstraintName)) {
                        tableIndexList.remove(relConstraintName);
                    } else {
                        if (checkFkIdx) {
                            // if not, create one
                            String noIdxMessage = "No Index [" + relConstraintName + "] found for entity [" + entityName + "]";
                            if (messages != null)
                                messages.add(noIdxMessage);
                            if (Debug.infoOn())
                                Debug.logInfo(noIdxMessage, module);
                            if (addMissing) {
                                String errMsg = createForeignKeyIndex(entity, modelRelation, datasourceInfo.getConstraintNameClipLength());
                                if (UtilValidate.isNotEmpty(errMsg)) {
                                    String message = "Could not create foreign key index " + relConstraintName + " for entity [" + entity.getEntityName() + "]: " + errMsg;
                                    Debug.logError(message, module);
                                    if (messages != null)
                                        messages.add(message);
                                } else {
                                    String message = "Created foreign key index " + relConstraintName + " for entity [" + entity.getEntityName() + "]";
                                    Debug.logVerbose(message, module);
                                    if (messages != null)
                                        messages.add(message);
                                    createdConstraints = true;
                                    numIndicesCreated++;
                                }
                            }
                        }
                    }
                }
                if (createdConstraints) {
                    String message = "Created foreign key index/indices for entity [" + entity.getEntityName() + "]";
                    Debug.logImportant(message, module);
                    if (messages != null)
                        messages.add(message);
                }
                // go through each indice to see if an indice already exists
                boolean createdIndexes = false;
                Iterator<ModelIndex> indexes = entity.getIndexesIterator();
                while (indexes.hasNext()) {
                    ModelIndex modelIndex = indexes.next();
                    String relIndexName = makeIndexName(modelIndex, datasourceInfo.getConstraintNameClipLength());
                    String checkIndexName = needsUpperCase[0] ? relIndexName.toUpperCase() : relIndexName;
                    if (tableIndexList.contains(checkIndexName)) {
                        tableIndexList.remove(checkIndexName);
                    } else {
                        if (datasourceInfo.getCheckIndicesOnStart()) {
                            // if not, create one
                            String noIdxMessage = "No Index [" + relIndexName + "] found for entity [" + entityName + "]";
                            if (messages != null)
                                messages.add(noIdxMessage);
                            if (Debug.infoOn())
                                Debug.logInfo(noIdxMessage, module);
                            if (addMissing) {
                                String errMsg = createDeclaredIndex(entity, modelIndex);
                                if (UtilValidate.isNotEmpty(errMsg)) {
                                    String message = "Could not create index " + relIndexName + " for entity [" + entity.getEntityName() + "]: " + errMsg;
                                    Debug.logError(message, module);
                                    if (messages != null)
                                        messages.add(message);
                                } else {
                                    String message = "Created index " + relIndexName + " for entity [" + entity.getEntityName() + "]";
                                    Debug.logVerbose(message, module);
                                    if (messages != null)
                                        messages.add(message);
                                    createdIndexes = true;
                                    numIndicesCreated++;
                                }
                            }
                        }
                    }
                }
                if (createdIndexes) {
                    String message = "Created declared index/indices for entity [" + entity.getEntityName() + "]";
                    Debug.logImportant(message, module);
                    if (messages != null)
                        messages.add(message);
                }
                // show index key references that exist but are unknown
                if (tableIndexList != null) {
                    for (String indexLeft : tableIndexList) {
                        String message = "Unknown Index " + indexLeft + " found in table " + entity.getTableName(datasourceInfo);
                        Debug.logImportant(message, module);
                        if (messages != null)
                            messages.add(message);
                    }
                }
            }
        }
        if (numIndicesCreated > 0 && Debug.infoOn())
            Debug.logInfo("Created " + numIndicesCreated + " indices", module);
    }
    executor.shutdown();
    timer.timerString("Finished Checking Entity Database");
}
Also used : TreeSet(java.util.TreeSet) ResultSet(java.sql.ResultSet) Set(java.util.Set) SQLException(java.sql.SQLException) HashMap(java.util.HashMap) UtilTimer(org.apache.ofbiz.base.util.UtilTimer) ArrayList(java.util.ArrayList) ModelRelation(org.apache.ofbiz.entity.model.ModelRelation) ModelField(org.apache.ofbiz.entity.model.ModelField) ModelViewEntity(org.apache.ofbiz.entity.model.ModelViewEntity) ModelIndex(org.apache.ofbiz.entity.model.ModelIndex) ModelEntity(org.apache.ofbiz.entity.model.ModelEntity) LinkedList(java.util.LinkedList) ModelFieldType(org.apache.ofbiz.entity.model.ModelFieldType) ExecutorService(java.util.concurrent.ExecutorService) Future(java.util.concurrent.Future) HashMap(java.util.HashMap) Map(java.util.Map) ModelKeyMap(org.apache.ofbiz.entity.model.ModelKeyMap)

Example 3 with UtilTimer

use of org.apache.ofbiz.base.util.UtilTimer in project ofbiz-framework by apache.

the class ModelFieldTypeReader method getModelFieldTypeReader.

public static ModelFieldTypeReader getModelFieldTypeReader(String helperName) {
    Datasource datasourceInfo = EntityConfig.getDatasource(helperName);
    if (datasourceInfo == null) {
        throw new IllegalArgumentException("Could not find a datasource/helper with the name " + helperName);
    }
    String tempModelName = datasourceInfo.getFieldTypeName();
    ModelFieldTypeReader reader = readers.get(tempModelName);
    while (reader == null) {
        FieldType fieldTypeInfo = null;
        try {
            fieldTypeInfo = EntityConfig.getInstance().getFieldType(tempModelName);
        } catch (GenericEntityConfException e) {
            Debug.logWarning(e, "Exception thrown while getting field type config: ", module);
        }
        if (fieldTypeInfo == null) {
            throw new IllegalArgumentException("Could not find a field-type definition with name \"" + tempModelName + "\"");
        }
        ResourceHandler fieldTypeResourceHandler = new MainResourceHandler(EntityConfig.ENTITY_ENGINE_XML_FILENAME, fieldTypeInfo.getLoader(), fieldTypeInfo.getLocation());
        UtilTimer utilTimer = new UtilTimer();
        utilTimer.timerString("[ModelFieldTypeReader.getModelFieldTypeReader] Reading field types from " + fieldTypeResourceHandler.getLocation());
        Document document = null;
        try {
            document = fieldTypeResourceHandler.getDocument();
        } catch (GenericConfigException e) {
            Debug.logError(e, module);
            throw new IllegalStateException("Error loading field type file " + fieldTypeResourceHandler.getLocation());
        }
        Map<String, ModelFieldType> fieldTypeMap = createFieldTypeCache(document.getDocumentElement(), fieldTypeResourceHandler.getLocation());
        reader = readers.putIfAbsentAndGet(tempModelName, new ModelFieldTypeReader(fieldTypeMap));
        utilTimer.timerString("[ModelFieldTypeReader.getModelFieldTypeReader] Read " + fieldTypeMap.size() + " field types");
    }
    return reader;
}
Also used : Datasource(org.apache.ofbiz.entity.config.model.Datasource) GenericEntityConfException(org.apache.ofbiz.entity.GenericEntityConfException) UtilTimer(org.apache.ofbiz.base.util.UtilTimer) ResourceHandler(org.apache.ofbiz.base.config.ResourceHandler) MainResourceHandler(org.apache.ofbiz.base.config.MainResourceHandler) Document(org.w3c.dom.Document) FieldType(org.apache.ofbiz.entity.config.model.FieldType) GenericConfigException(org.apache.ofbiz.base.config.GenericConfigException) MainResourceHandler(org.apache.ofbiz.base.config.MainResourceHandler)

Example 4 with UtilTimer

use of org.apache.ofbiz.base.util.UtilTimer in project ofbiz-framework by apache.

the class ModelGroupReader method getGroupCache.

public Map<String, String> getGroupCache(String delegatorName) {
    if (this.groupCache == null) {
        // don't want to block here
        synchronized (ModelGroupReader.class) {
            // must check if null again as one of the blocked threads can still enter
            if (this.groupCache == null) {
                // now it's safe
                this.groupCache = new HashMap<>();
                this.groupNames = new TreeSet<>();
                UtilTimer utilTimer = new UtilTimer();
                // utilTimer.timerString("[ModelGroupReader.getGroupCache] Before getDocument");
                int i = 0;
                for (ResourceHandler entityGroupResourceHandler : this.entityGroupResourceHandlers) {
                    Document document = null;
                    try {
                        document = entityGroupResourceHandler.getDocument();
                    } catch (GenericConfigException e) {
                        Debug.logError(e, "Error loading entity group model", module);
                    }
                    if (document == null) {
                        this.groupCache = null;
                        return null;
                    }
                    // utilTimer.timerString("[ModelGroupReader.getGroupCache] Before getDocumentElement");
                    Element docElement = document.getDocumentElement();
                    if (docElement == null) {
                        continue;
                    }
                    docElement.normalize();
                    Node curChild = docElement.getFirstChild();
                    if (curChild != null) {
                        utilTimer.timerString("[ModelGroupReader.getGroupCache] Before start of entity loop");
                        do {
                            if (curChild.getNodeType() == Node.ELEMENT_NODE && "entity-group".equals(curChild.getNodeName())) {
                                Element curEntity = (Element) curChild;
                                String entityName = UtilXml.checkEmpty(curEntity.getAttribute("entity")).intern();
                                String groupName = UtilXml.checkEmpty(curEntity.getAttribute("group")).intern();
                                try {
                                    if (null == EntityConfig.getInstance().getDelegator(delegatorName).getGroupDataSource(groupName)) {
                                        Debug.logError("The declared group name " + groupName + " has no corresponding group-map in entityengine.xml: ", module);
                                    }
                                } catch (GenericEntityConfException e) {
                                    Debug.logWarning(e, "Exception thrown while getting group name: ", module);
                                }
                                this.groupNames.add(groupName);
                                this.groupCache.put(entityName, groupName);
                                // utilTimer.timerString("  After entityEntityName -- " + i + " --");
                                i++;
                            }
                        } while ((curChild = curChild.getNextSibling()) != null);
                    } else {
                        Debug.logWarning("[ModelGroupReader.getGroupCache] No child nodes found.", module);
                    }
                }
                utilTimer.timerString("[ModelGroupReader.getGroupCache] FINISHED - Total Entity-Groups: " + i + " FINISHED");
            }
        }
    }
    return this.groupCache;
}
Also used : GenericConfigException(org.apache.ofbiz.base.config.GenericConfigException) GenericEntityConfException(org.apache.ofbiz.entity.GenericEntityConfException) DelegatorElement(org.apache.ofbiz.entity.config.model.DelegatorElement) Element(org.w3c.dom.Element) Node(org.w3c.dom.Node) UtilTimer(org.apache.ofbiz.base.util.UtilTimer) ResourceHandler(org.apache.ofbiz.base.config.ResourceHandler) MainResourceHandler(org.apache.ofbiz.base.config.MainResourceHandler) Document(org.w3c.dom.Document)

Example 5 with UtilTimer

use of org.apache.ofbiz.base.util.UtilTimer in project ofbiz-framework by apache.

the class ModelReader method getEntityCache.

public Map<String, ModelEntity> getEntityCache() throws GenericEntityException {
    if (entityCache == null) {
        // don't want to block here
        synchronized (ModelReader.class) {
            // must check if null again as one of the blocked threads can still enter
            if (entityCache == null) {
                // now it's safe
                numEntities = 0;
                numViewEntities = 0;
                numFields = 0;
                numRelations = 0;
                numAutoRelations = 0;
                entityCache = new HashMap<>();
                List<ModelViewEntity> tempViewEntityList = new LinkedList<>();
                List<Element> tempExtendEntityElementList = new LinkedList<>();
                UtilTimer utilTimer = new UtilTimer();
                for (ResourceHandler entityResourceHandler : entityResourceHandlers) {
                    // utilTimer.timerString("Before getDocument in file " + entityFileName);
                    Document document = null;
                    try {
                        document = entityResourceHandler.getDocument();
                    } catch (GenericConfigException e) {
                        throw new GenericEntityConfException("Error getting document from resource handler", e);
                    }
                    if (document == null) {
                        throw new GenericEntityConfException("Could not get document for " + entityResourceHandler.toString());
                    }
                    // utilTimer.timerString("Before getDocumentElement in " +
                    // entityResourceHandler.toString());
                    Element docElement = document.getDocumentElement();
                    if (docElement == null) {
                        return null;
                    }
                    docElement.normalize();
                    Node curChild = docElement.getFirstChild();
                    ModelInfo def = ModelInfo.createFromElements(ModelInfo.DEFAULT, docElement);
                    int i = 0;
                    if (curChild != null) {
                        utilTimer.timerString("Before start of entity loop in " + entityResourceHandler.toString());
                        do {
                            boolean isEntity = "entity".equals(curChild.getNodeName());
                            boolean isViewEntity = "view-entity".equals(curChild.getNodeName());
                            boolean isExtendEntity = "extend-entity".equals(curChild.getNodeName());
                            if ((isEntity || isViewEntity) && curChild.getNodeType() == Node.ELEMENT_NODE) {
                                i++;
                                ModelEntity modelEntity = buildEntity(entityResourceHandler, (Element) curChild, i, def);
                                // put the view entity in a list to get ready for the second pass to populate fields...
                                if (isViewEntity) {
                                    tempViewEntityList.add((ModelViewEntity) modelEntity);
                                } else {
                                    entityCache.put(modelEntity.getEntityName(), modelEntity);
                                }
                            } else if (isExtendEntity && curChild.getNodeType() == Node.ELEMENT_NODE) {
                                tempExtendEntityElementList.add((Element) curChild);
                            }
                        } while ((curChild = curChild.getNextSibling()) != null);
                    } else {
                        Debug.logWarning("No child nodes found.", module);
                    }
                    utilTimer.timerString("Finished " + entityResourceHandler.toString() + " - Total Entities: " + i + " FINISHED");
                }
                // all entity elements in, now go through extend-entity elements and add their stuff
                for (Element extendEntityElement : tempExtendEntityElementList) {
                    String entityName = UtilXml.checkEmpty(extendEntityElement.getAttribute("entity-name"));
                    ModelEntity modelEntity = entityCache.get(entityName);
                    if (modelEntity == null)
                        throw new GenericEntityConfException("Entity to extend does not exist: " + entityName);
                    modelEntity.addExtendEntity(this, extendEntityElement);
                }
                // do a pass on all of the view entities now that all of the entities have loaded and populate the fields
                while (!tempViewEntityList.isEmpty()) {
                    int startSize = tempViewEntityList.size();
                    Iterator<ModelViewEntity> mveIt = tempViewEntityList.iterator();
                    TEMP_VIEW_LOOP: while (mveIt.hasNext()) {
                        ModelViewEntity curViewEntity = mveIt.next();
                        for (ModelViewEntity.ModelMemberEntity mve : curViewEntity.getAllModelMemberEntities()) {
                            if (!entityCache.containsKey(mve.getEntityName())) {
                                continue TEMP_VIEW_LOOP;
                            }
                        }
                        mveIt.remove();
                        curViewEntity.populateFields(this);
                        for (ModelViewEntity.ModelMemberEntity mve : curViewEntity.getAllModelMemberEntities()) {
                            ModelEntity me = entityCache.get(mve.getEntityName());
                            me.addViewEntity(curViewEntity);
                        }
                        entityCache.put(curViewEntity.getEntityName(), curViewEntity);
                    }
                    if (tempViewEntityList.size() == startSize) {
                        // that have some reference problem.
                        break;
                    }
                }
                if (!tempViewEntityList.isEmpty()) {
                    StringBuilder sb = new StringBuilder("View entities reference non-existant members:\n");
                    Set<String> allViews = new HashSet<>();
                    for (ModelViewEntity curViewEntity : tempViewEntityList) {
                        allViews.add(curViewEntity.getEntityName());
                    }
                    for (ModelViewEntity curViewEntity : tempViewEntityList) {
                        Set<String> perViewMissingEntities = new HashSet<>();
                        Iterator<ModelViewEntity.ModelMemberEntity> mmeIt = curViewEntity.getAllModelMemberEntities().iterator();
                        while (mmeIt.hasNext()) {
                            ModelViewEntity.ModelMemberEntity mme = mmeIt.next();
                            String memberEntityName = mme.getEntityName();
                            if (!entityCache.containsKey(memberEntityName)) {
                                // check to see if it is a view
                                if (!allViews.contains(memberEntityName)) {
                                    // not a view, it's a real missing entity
                                    perViewMissingEntities.add(memberEntityName);
                                }
                            }
                        }
                        for (String perViewMissingEntity : perViewMissingEntities) {
                            sb.append("\t[").append(curViewEntity.getEntityName()).append("] missing member entity [").append(perViewMissingEntity).append("]\n");
                        }
                    }
                    throw new GenericEntityConfException(sb.toString());
                }
                // auto-create relationships
                Set<String> orderedMessages = new TreeSet<>();
                for (String curEntityName : new TreeSet<>(this.getEntityNames())) {
                    ModelEntity curModelEntity = this.getModelEntity(curEntityName);
                    if (curModelEntity instanceof ModelViewEntity) {
                    // for view-entities auto-create relationships for all member-entity
                    // relationships that have all corresponding fields in the view-entity
                    } else {
                        // for entities auto-create many relationships for all type one relationships
                        // just in case we add a new relation to the same entity, keep in a separate
                        // list and add them at the end
                        List<ModelRelation> newSameEntityRelations = new LinkedList<>();
                        Iterator<ModelRelation> relationsIter = curModelEntity.getRelationsIterator();
                        while (relationsIter.hasNext()) {
                            ModelRelation modelRelation = relationsIter.next();
                            if (("one".equals(modelRelation.getType()) || "one-nofk".equals(modelRelation.getType())) && !modelRelation.isAutoRelation()) {
                                ModelEntity relatedEnt = null;
                                try {
                                    relatedEnt = this.getModelEntity(modelRelation.getRelEntityName());
                                } catch (GenericModelException e) {
                                    throw new GenericModelException("Error getting related entity [" + modelRelation.getRelEntityName() + "] definition from entity [" + curEntityName + "]", e);
                                }
                                // create the new relationship even if one exists so we can show what we are
                                // looking for in the info message
                                // don't do relationship to the same entity, unless title is "Parent", then do a
                                // "Child" automatically
                                String title = modelRelation.getTitle();
                                if (curModelEntity.getEntityName().equals(relatedEnt.getEntityName()) && "Parent".equals(title)) {
                                    title = "Child";
                                }
                                String description = "";
                                String type = "";
                                String relEntityName = curModelEntity.getEntityName();
                                String fkName = "";
                                ArrayList<ModelKeyMap> keyMaps = new ArrayList<>();
                                boolean isAutoRelation = true;
                                Set<String> curEntityKeyFields = new HashSet<>();
                                for (ModelKeyMap curkm : modelRelation.getKeyMaps()) {
                                    keyMaps.add(new ModelKeyMap(curkm.getRelFieldName(), curkm.getFieldName()));
                                    curEntityKeyFields.add(curkm.getFieldName());
                                }
                                keyMaps.trimToSize();
                                // the complete pk of the relEntity
                                if (curModelEntity.containsAllPkFieldNames(curEntityKeyFields)) {
                                    // always use one-nofk, we don't want auto-fks getting in for these automatic ones
                                    type = "one-nofk";
                                    // to keep it clean, remove any additional keys that aren't part of the PK
                                    List<String> curPkFieldNames = curModelEntity.getPkFieldNames();
                                    Iterator<ModelKeyMap> nrkmIter = keyMaps.iterator();
                                    while (nrkmIter.hasNext()) {
                                        ModelKeyMap nrkm = nrkmIter.next();
                                        String checkField = nrkm.getRelFieldName();
                                        if (!curPkFieldNames.contains(checkField)) {
                                            nrkmIter.remove();
                                        }
                                    }
                                } else {
                                    type = "many";
                                }
                                ModelRelation newRel = ModelRelation.create(relatedEnt, description, type, title, relEntityName, fkName, keyMaps, isAutoRelation);
                                ModelRelation existingRelation = relatedEnt.getRelation(title + curModelEntity.getEntityName());
                                if (existingRelation == null) {
                                    numAutoRelations++;
                                    if (curModelEntity.getEntityName().equals(relatedEnt.getEntityName())) {
                                        newSameEntityRelations.add(newRel);
                                    } else {
                                        relatedEnt.addRelation(newRel);
                                    }
                                } else {
                                    if (newRel.equals(existingRelation)) {
                                        // don't warn if the target title+entity = current title+entity
                                        if (Debug.infoOn() && !(title + curModelEntity.getEntityName()).equals(modelRelation.getTitle() + modelRelation.getRelEntityName())) {
                                            // String errorMsg = "Relation already exists to entity [] with title ["
                                            // + targetTitle + "],from entity []";
                                            String message = "Entity [" + relatedEnt.getPackageName() + ":" + relatedEnt.getEntityName() + "] already has identical relationship to entity [" + curModelEntity.getEntityName() + "] title [" + title + "]; would auto-create: type [" + newRel.getType() + "] and fields [" + newRel.keyMapString(",", "") + "]";
                                            orderedMessages.add(message);
                                        }
                                    } else {
                                        String message = "Existing relationship with the same name, but different specs found from what would be auto-created for Entity [" + relatedEnt.getEntityName() + "] and relationship to entity [" + curModelEntity.getEntityName() + "] title [" + title + "]; would auto-create: type [" + newRel.getType() + "] and fields [" + newRel.keyMapString(",", "") + "]";
                                        if (Debug.verboseOn())
                                            Debug.logVerbose(message, module);
                                    }
                                }
                            }
                        }
                        if (newSameEntityRelations.size() > 0) {
                            for (ModelRelation newRel : newSameEntityRelations) {
                                curModelEntity.addRelation(newRel);
                            }
                        }
                    }
                }
                if (Debug.infoOn()) {
                    for (String message : orderedMessages) {
                        Debug.logInfo(message, module);
                    }
                    Debug.logInfo("Finished loading entities; #Entities=" + numEntities + " #ViewEntities=" + numViewEntities + " #Fields=" + numFields + " #Relationships=" + numRelations + " #AutoRelationships=" + numAutoRelations, module);
                }
            }
        }
    }
    return entityCache;
}
Also used : GenericModelException(org.apache.ofbiz.entity.GenericModelException) GenericEntityConfException(org.apache.ofbiz.entity.GenericEntityConfException) DelegatorElement(org.apache.ofbiz.entity.config.model.DelegatorElement) Element(org.w3c.dom.Element) Node(org.w3c.dom.Node) UtilTimer(org.apache.ofbiz.base.util.UtilTimer) ArrayList(java.util.ArrayList) ResourceHandler(org.apache.ofbiz.base.config.ResourceHandler) MainResourceHandler(org.apache.ofbiz.base.config.MainResourceHandler) Document(org.w3c.dom.Document) EntityModelReader(org.apache.ofbiz.entity.config.model.EntityModelReader) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) LinkedList(java.util.LinkedList) GenericConfigException(org.apache.ofbiz.base.config.GenericConfigException)

Aggregations

UtilTimer (org.apache.ofbiz.base.util.UtilTimer)6 GenericConfigException (org.apache.ofbiz.base.config.GenericConfigException)4 Document (org.w3c.dom.Document)4 MainResourceHandler (org.apache.ofbiz.base.config.MainResourceHandler)3 ResourceHandler (org.apache.ofbiz.base.config.ResourceHandler)3 GenericEntityConfException (org.apache.ofbiz.entity.GenericEntityConfException)3 Element (org.w3c.dom.Element)3 Node (org.w3c.dom.Node)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 LinkedList (java.util.LinkedList)2 TreeSet (java.util.TreeSet)2 DelegatorElement (org.apache.ofbiz.entity.config.model.DelegatorElement)2 ServletContextHashModel (freemarker.ext.servlet.ServletContextHashModel)1 IOException (java.io.IOException)1 ResultSet (java.sql.ResultSet)1 SQLException (java.sql.SQLException)1 HashSet (java.util.HashSet)1 LinkedHashMap (java.util.LinkedHashMap)1 Map (java.util.Map)1