All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jaxio.celerio.model.Project Maven / Gradle / Ivy

There is a newer version: 4.0.23
Show newest version
/*
 * Copyright 2015 JAXIO http://www.jaxio.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.jaxio.celerio.model;

import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.collect.Sets;
import com.jaxio.celerio.convention.ClassType;
import com.jaxio.celerio.convention.GeneratedPackage;
import com.jaxio.celerio.model.support.EntityPredicates;
import com.jaxio.celerio.util.support.SimpleListHolder;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.springframework.util.Assert;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.google.common.collect.Iterables.any;
import static com.google.common.collect.Iterables.find;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newHashMap;
import static com.google.common.collect.Sets.newHashSet;
import static com.jaxio.celerio.model.support.EntityPredicates.*;
import static java.util.Collections.unmodifiableList;

@Slf4j
@Getter
public class Project implements Map {
    private List currentEntities = newArrayList();
    @Getter(value = AccessLevel.PRIVATE)
    private Map currentEntitiesByTableName = newHashMap();
    @Getter(value = AccessLevel.PRIVATE)
    private Map currentEntitiesByName = newHashMap();
    private SimpleListHolder entities = newEntityHolder();
    private SimpleListHolder rootEntities = newEntityHolder(ROOT);
    private SimpleListHolder entitiesWithFiles = newEntityHolder(HAS_FILE);
    private SimpleListHolder virtuals = newEntityHolder(VIRTUAL);
    private SimpleListHolder views = newEntityHolder(VIEW);
    private SimpleListHolder tables = newEntityHolder(TABLE);
    private SimpleListHolder withoutManyToManyJoinEntities = newEntityHolder(NOT_MANY_TO_MANY_JOIN);
    private SimpleListHolder search = newEntityHolder(SEARCH);
    private Map spis = newHashMap();

    public Project() {
    }

    public Project(List entities) {
        this.currentEntities = entities;
    }

    private SimpleListHolder newEntityHolder() {
        return new SimpleListHolder(currentEntities);
    }

    private SimpleListHolder newEntityHolder(Predicate predicate) {
        return new SimpleListHolder(currentEntities, predicate, "name");
    }

    public void reset() {
        currentEntities.clear();
        currentEntitiesByTableName.clear();
        currentEntitiesByName.clear();
        entities = new SimpleListHolder(currentEntities);
    }

    public void addEntity(Entity entity) {
        if (log.isDebugEnabled()) {
            log.debug("Adding entity entityName=" + entity.getName() + " tableName=" + entity.getTableName());
        }

        putEntityByName(entity);
        currentEntities.add(entity);
    }

    // -------------------------------
    // Entity by name
    // -------------------------------

    public List getCurrentEntities() {
        return unmodifiableList(currentEntities);
    }

    private void putEntityByName(Entity entity) {
        Assert.isTrue(!hasEntityByName(entity.getName()), "An entity with the same name is already present!: " + entity.getName());
        currentEntitiesByName.put(entity.getName().toUpperCase(), entity);
    }

    public boolean hasEntityByName(String entityName) {
        return currentEntitiesByName.get(entityName.toUpperCase()) != null;
    }

    // -------------------------------
    // Entity by table name
    // -------------------------------

    public Entity getEntityByName(String entityName) {
        Entity entity = currentEntitiesByName.get(entityName.toUpperCase());
        Assert.notNull(entity, "You must be sure that an entity is present. Entity name=" + entityName);
        return entity;
    }

    /**
     * Store 1 entity per table name. In case of inheritance you must pass the root entity only.
     */
    public void putEntityByTableName(Entity entity) {
        Assert.isTrue(entity.hasTableName(), "Expecting a table name for the entity: " + entity.getName());
        Assert.isTrue(!hasEntityByTableName(entity.getTableName()), "Entity was already added!: " + entity.getTableName());
        currentEntitiesByTableName.put(entity.getTableName().toUpperCase(), entity);
    }

    public boolean hasEntityByTableName(String tableName) {
        return currentEntitiesByTableName.containsKey(tableName.toUpperCase());
    }

    // -------------------------------
    // Account Convention
    // -------------------------------

    /**
     * Return the entity corresponding to the passed table. In case of inheritance, the root entity is returned.
     */
    public Entity getEntityByTableName(String tableName) {
        return currentEntitiesByTableName.get(tableName.toUpperCase());
    }

    public boolean isAccountEntityPresent() {
        return any(currentEntities, ACCOUNT);
    }

    public Entity getAccountEntity() {
        return find(currentEntities, ACCOUNT);
    }

    public boolean isRoleEntityPresent() {
        return any(currentEntities, ROLE);
    }

    public Entity getRoleEntity() {
        return find(currentEntities, ROLE);
    }

    public boolean isAuditLogPresent() {
        return any(currentEntities, AUDIT_LOG);
    }

    public Entity getAuditLog() {
        return find(currentEntities, AUDIT_LOG);
    }

    public boolean isSavedSearchPresent() {
        return any(currentEntities, SAVED_SEARCH);
    }

    public Entity getSavedSearch() {
        return find(currentEntities, SAVED_SEARCH);
    }

    public String getPackagesToScan() {
        Set packages = newHashSet();
        for (Entity entity : entities.getList()) {
            packages.add(entity.getEntityConfig().getRootPackage());
        }
        for (ClassType classType : ClassType.values()) {
            packages.add(classType.getRootPackage());
        }
        for (GeneratedPackage generatedPackage : GeneratedPackage.values()) {
            packages.add(generatedPackage.getRootPackage());
        }
        return Joiner.on(',').skipNulls().join(packages);
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
    }

    // TODO: we should have a central place for enum types
    public Set getEnumTypes() {
        Set ret = Sets.newTreeSet();
        for (Entity entity : getEntities().getList()) {
            for (Attribute attribute : entity.getAttributes().getList()) {
                if (attribute.isEnum()) {
                    ret.add(attribute.getEnumType());
                }
            }
        }
        return ret;
    }

    public boolean isDefaultSchema() {
        if (!hasTableNames("ADDRESS", "ACCOUNT", "ROLE", "ACCOUNT_ROLE", "DOCUMENT", "BOOK", "MORE_TYPES_DEMO", "LEGACY")) {
            return false;
        }
        if (!hasHomeAddress()) {
            return false;
        }
        return true;
    }

    private boolean hasHomeAddress() {
        Entity account = getEntityByName("Account");
        for (Relation r : account.getXToOne().getList()) {
            if (r.getTo().getVar().equals("homeAddress")) {
                return true;
            }
        }
        return false;
    }

    private boolean hasTableNames(String... tableNames) {
        for (String tableName : tableNames) {
            if (!hasEntityByTableName(tableName)) {
                return false;
            }
        }
        return true;
    }

    public boolean getHibernateSearchUsed() {
        return any(currentEntities, EntityPredicates.IS_INDEXED);
    }

    /**
     * Helper to print comma, semi colon, double slash etc. inside velocity foreach loop.
* Example: ${enumValue.name}("$enumValue.value")$project.print($velocityHasNext, ", //", ";") * * @param velocityHasNext special velocity var available inside foreach loop. * @param whenTrue the string to return when velocityHasNext is true * @param whenFalse the string to to return when velocityHasNext is false */ public String print(boolean velocityHasNext, String whenTrue, String whenFalse) { return velocityHasNext ? whenTrue : whenFalse; } // ------------------------------------ // SPI are put in a Map so we can access // from velocity templates as if we had getter. // ------------------------------------ /** * Helper to print comma, semi colon, double slash etc. inside velocity foreach loop.
* Example: ${enumValue.name}("$enumValue.value")$project.print($velocityHasNext, ", //") * * @param velocityHasNext special velocity var available inside foreach loop. * @param whenTrue the string to return when velocityHasNext is true * @return whenTrue the string to return when velocityHasNext is true, an empty String otherwise. */ public String print(boolean velocityHasNext, String whenTrue) { return velocityHasNext ? whenTrue : ""; } @Override public void clear() { spis.clear(); } @Override public boolean containsKey(Object arg0) { return spis.containsKey(arg0); } @Override public boolean containsValue(Object arg0) { return spis.containsValue(arg0); } @Override public Set> entrySet() { return spis.entrySet(); } @Override public Object get(Object arg0) { Object o = spis.get(arg0); Preconditions.checkNotNull(o, "No SPI having its var=" + arg0 + " was found. Tip: in your template for predicate method, use always ref.isSomething() instead of xxx.something"); return o; } @Override public boolean isEmpty() { return spis.isEmpty(); } @Override public Set keySet() { return spis.keySet(); } @Override public Object put(String arg0, Object arg1) { return spis.put(arg0, arg1); } @Override public void putAll(Map arg0) { spis.putAll(arg0); } @Override public Object remove(Object arg0) { return spis.remove(arg0); } @Override public int size() { return spis.size(); } @Override public Collection values() { return spis.values(); } }