Esempio n. 1
0
  protected static void addEcaDefinitions(
      ResourceHandler handler, Map<String, Map<String, List<EntityEcaRule>>> ecaCache) {
    Element rootElement = null;
    try {
      rootElement = handler.getDocument().getDocumentElement();
    } catch (GenericConfigException e) {
      Debug.logError(e, module);
      return;
    }

    int numDefs = 0;
    for (Element e : UtilXml.childElementList(rootElement, "eca")) {
      String entityName = e.getAttribute("entity");
      String eventName = e.getAttribute("event");
      Map<String, List<EntityEcaRule>> eventMap = ecaCache.get(entityName);
      List<EntityEcaRule> rules = null;
      if (eventMap == null) {
        eventMap = FastMap.newInstance();
        rules = FastList.newInstance();
        ecaCache.put(entityName, eventMap);
        eventMap.put(eventName, rules);
      } else {
        rules = eventMap.get(eventName);
        if (rules == null) {
          rules = FastList.newInstance();
          eventMap.put(eventName, rules);
        }
      }
      rules.add(new EntityEcaRule(e));
      numDefs++;
    }
    try {
      Debug.logImportant(
          "Loaded ["
              + numDefs
              + "] Entity ECA definitions from "
              + handler.getFullLocation()
              + " in loader "
              + handler.getLoaderName(),
          module);
    } catch (GenericConfigException e) {
      Debug.logError(e, module);
      return;
    }
  }
Esempio n. 2
0
  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<String, ModelEntity>();
          List<ModelViewEntity> tempViewEntityList = FastList.newInstance();
          List<Element> tempExtendEntityElementList = FastList.newInstance();

          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 = new ModelInfo();
            def.populateFromElements(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 = (ModelEntity) entityCache.get(mve.getEntityName());
                me.addViewEntity(curViewEntity);
              }
              entityCache.put(curViewEntity.getEntityName(), curViewEntity);
            }
            if (tempViewEntityList.size() == startSize) {
              // Oops, the remaining views reference other entities
              // that can't be found, or they reference other views
              // that have some reference problem.
              break;
            }
          }
          if (!tempViewEntityList.isEmpty()) {
            StringBuilder sb = new StringBuilder("View entities reference non-existant members:\n");
            Set<String> allViews = FastSet.newInstance();
            for (ModelViewEntity curViewEntity : tempViewEntityList) {
              allViews.add(curViewEntity.getEntityName());
            }
            for (ModelViewEntity curViewEntity : tempViewEntityList) {
              Set<String> perViewMissingEntities = FastSet.newInstance();
              Iterator<ModelViewEntity.ModelMemberEntity> mmeIt =
                  curViewEntity.getAllModelMemberEntities().iterator();
              while (mmeIt.hasNext()) {
                ModelViewEntity.ModelMemberEntity mme = mmeIt.next();
                String memberEntityName = mme.getEntityName();
                if (!entityCache.containsKey(memberEntityName)) {
                  // this member is not a real entity
                  // 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
          TreeSet<String> orderedMessages = new TreeSet<String>();
          for (String curEntityName : new TreeSet<String>(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 = FastList.newInstance();

              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);
                  }
                  if (relatedEnt != null) {
                    // don't do relationship to the same entity, unless title is "Parent", then do a
                    // "Child" automatically
                    String targetTitle = modelRelation.getTitle();
                    if (curModelEntity.getEntityName().equals(relatedEnt.getEntityName())
                        && "Parent".equals(targetTitle)) {
                      targetTitle = "Child";
                    }

                    // create the new relationship even if one exists so we can show what we are
                    // looking for in the info message
                    ModelRelation newRel = new ModelRelation();
                    newRel.setModelEntity(relatedEnt);
                    newRel.setRelEntityName(curModelEntity.getEntityName());
                    newRel.setTitle(targetTitle);
                    newRel.setAutoRelation(true);
                    Set<String> curEntityKeyFields = FastSet.newInstance();
                    for (int kmn = 0; kmn < modelRelation.getKeyMapsSize(); kmn++) {
                      ModelKeyMap curkm = modelRelation.getKeyMap(kmn);
                      ModelKeyMap newkm = new ModelKeyMap();
                      newRel.addKeyMap(newkm);
                      newkm.setFieldName(curkm.getRelFieldName());
                      newkm.setRelFieldName(curkm.getFieldName());
                      curEntityKeyFields.add(curkm.getFieldName());
                    }
                    // decide whether it should be one or many by seeing if the key map represents
                    // 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
                      newRel.setType("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 = newRel.getKeyMapsIterator();
                      while (nrkmIter.hasNext()) {
                        ModelKeyMap nrkm = nrkmIter.next();
                        String checkField = nrkm.getRelFieldName();
                        if (!curPkFieldNames.contains(checkField)) {
                          nrkmIter.remove();
                        }
                      }
                    } else {
                      newRel.setType("many");
                    }

                    ModelRelation existingRelation =
                        relatedEnt.getRelation(targetTitle + 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 (!(targetTitle + 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 ["
                                  + targetTitle
                                  + "]; 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 ["
                                + targetTitle
                                + "]; would auto-create: type ["
                                + newRel.getType()
                                + "] and fields ["
                                + newRel.keyMapString(",", "")
                                + "]";
                        Debug.logVerbose(message, module);
                      }
                    }
                  } else {
                    String errorMsg =
                        "Could not find related entity ["
                            + modelRelation.getRelEntityName()
                            + "], no reverse relation added.";
                    Debug.logWarning(errorMsg, module);
                  }
                }
              }

              if (newSameEntityRelations.size() > 0) {
                for (ModelRelation newRel : newSameEntityRelations) {
                  curModelEntity.addRelation(newRel);
                }
              }
            }
          }

          for (String message : orderedMessages) {
            Debug.logInfo(message, module);
          }

          Debug.log(
              "FINISHED LOADING ENTITIES - ALL FILES; #Entities="
                  + numEntities
                  + " #ViewEntities="
                  + numViewEntities
                  + " #Fields="
                  + numFields
                  + " #Relationships="
                  + numRelations
                  + " #AutoRelationships="
                  + numAutoRelations,
              module);
        }
      }
    }
    return entityCache;
  }
Esempio n. 3
0
  private ModelEntity buildEntity(
      ResourceHandler entityResourceHandler, Element curEntityElement, int i, ModelInfo def)
      throws GenericEntityException {
    boolean isEntity = "entity".equals(curEntityElement.getNodeName());
    String entityName = UtilXml.checkEmpty(curEntityElement.getAttribute("entity-name")).intern();

    // add entityName to appropriate resourceHandlerEntities collection
    Collection<String> resourceHandlerEntityNames =
        resourceHandlerEntities.get(entityResourceHandler);

    if (resourceHandlerEntityNames == null) {
      resourceHandlerEntityNames = FastList.newInstance();
      resourceHandlerEntities.put(entityResourceHandler, resourceHandlerEntityNames);
    }
    resourceHandlerEntityNames.add(entityName);

    // check to see if entity with same name has already been read
    if (entityCache.containsKey(entityName)) {
      Debug.logWarning(
          "WARNING: Entity "
              + entityName
              + " is defined more than once, most recent will over-write "
              + "previous definition(s)",
          module);
      Debug.logWarning(
          "WARNING: Entity "
              + entityName
              + " was found in "
              + entityResourceHandler
              + ", but was already defined in "
              + entityResourceHandlerMap.get(entityName).toString(),
          module);
    }

    // add entityName, entityFileName pair to entityResourceHandlerMap map
    entityResourceHandlerMap.put(entityName, entityResourceHandler);

    // utilTimer.timerString("  After entityEntityName -- " + i + " --");
    // ModelEntity entity = createModelEntity(curEntity, utilTimer);

    ModelEntity modelEntity = null;
    if (isEntity) {
      modelEntity = createModelEntity(curEntityElement, null, def);
    } else {
      modelEntity = createModelViewEntity(curEntityElement, null, def);
    }

    String resourceLocation = entityResourceHandler.getLocation();
    try {
      resourceLocation = entityResourceHandler.getURL().toExternalForm();
    } catch (GenericConfigException e) {
      Debug.logError(e, "Could not get resource URL", module);
    }

    // utilTimer.timerString("  After createModelEntity -- " + i + " --");
    if (modelEntity != null) {
      modelEntity.setLocation(resourceLocation);
      // utilTimer.timerString("  After entityCache.put -- " + i + " --");
      if (isEntity) {
        if (Debug.verboseOn()) Debug.logVerbose("-- [Entity]: #" + i + ": " + entityName, module);
      } else {
        if (Debug.verboseOn())
          Debug.logVerbose("-- [ViewEntity]: #" + i + ": " + entityName, module);
      }
    } else {
      Debug.logWarning(
          "-- -- ENTITYGEN ERROR:getModelEntity: Could not create "
              + "entity for entityName: "
              + entityName,
          module);
    }
    return modelEntity;
  }