com.flexive.core.search.cmis.model.SingleTableReference.java Source code

Java tutorial

Introduction

Here is the source code for com.flexive.core.search.cmis.model.SingleTableReference.java

Source

/***************************************************************
 *  This file is part of the [fleXive](R) framework.
 *
 *  Copyright (c) 1999-2014
 *  UCS - unique computing solutions gmbh (http://www.ucs.at)
 *  All rights reserved
 *
 *  The [fleXive](R) project is free software; you can redistribute
 *  it and/or modify it under the terms of the GNU Lesser General Public
 *  License version 2.1 or higher as published by the Free Software Foundation.
 *
 *  The GNU Lesser General Public License can be found at
 *  http://www.gnu.org/licenses/lgpl.html.
 *  A copy is found in the textfile LGPL.txt and important notices to the
 *  license from the author are found in LICENSE.txt distributed with
 *  these libraries.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  For further information about UCS - unique computing solutions gmbh,
 *  please see the company website: http://www.ucs.at
 *
 *  For further information about [fleXive](R), please see the
 *  project website: http://www.flexive.org
 *
 *
 *  This copyright notice MUST APPEAR in all copies of the file!
 ***************************************************************/
package com.flexive.core.search.cmis.model;

import com.flexive.core.search.PropertyEntry;
import com.flexive.shared.cmis.CmisVirtualProperty;
import com.flexive.shared.exceptions.FxRuntimeException;
import com.flexive.shared.structure.FxEnvironment;
import com.flexive.shared.structure.FxProperty;
import com.flexive.shared.structure.FxPropertyAssignment;
import com.flexive.shared.structure.FxType;
import com.google.common.collect.Lists;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.*;

/**
 * A reference to a single table, with an optional alias.
 *
 * @author Daniel Lichtenberger (daniel.lichtenberger@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
 * @version $Rev$
 */
public class SingleTableReference implements TableReference {
    private static final Log LOG = LogFactory.getLog(SingleTableReference.class);

    private final String alias;
    private final List<FxType> referencedTypes;
    private final FxType baseType;

    public SingleTableReference(FxEnvironment env, String name, String alias) {
        this.alias = escapeTableAlias(alias);
        final List<FxType> types;
        if ("root".equalsIgnoreCase(name)) {
            // treat root type as a special case, because the API won't return any derived types
            this.baseType = env.getType(FxType.ROOT_ID);
            types = Lists.newArrayList();
            types.add(baseType);
            for (FxType type : env.getTypes()) {
                if (type.getId() != FxType.ROOT_ID) {
                    types.add(type);
                }
            }
        } else if ("cmis:document".equalsIgnoreCase(name)) {
            // select all types that are not folders
            this.baseType = env.getType(FxType.ROOT_ID);
            types = Lists.newArrayList();
            for (FxType type : env.getTypes()) {
                if (!type.isDerivedFrom(FxType.FOLDER)) {
                    types.add(type);
                }
            }
        } else if ("cmis:folder".equalsIgnoreCase(name)) {
            this.baseType = env.getType(FxType.FOLDER);
            types = Lists.newArrayList(baseType.getDerivedTypes(true, true));
        } else {
            // normal type, add type and all subtypes
            this.baseType = env.getType(name);
            types = Lists.newArrayList(baseType.getDerivedTypes(true, true));
        }
        this.referencedTypes = Collections.unmodifiableList(types);
    }

    public SingleTableReference(FxEnvironment env, String name) {
        this(env, name, name);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public TableReference findByAlias(String alias) {
        return this.alias.equals(alias) ? this : null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getAlias() {
        return alias;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<String> getReferencedAliases() {
        return Arrays.asList(alias);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<FxType> getReferencedTypes() {
        return referencedTypes;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isPropertySecurityEnabled() {
        for (FxType type : referencedTypes) {
            if (type.isUsePropertyPermissions()) {
                return true;
            }
        }
        return false;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<FxPropertyAssignment> resolvePropertyAssignment(FxEnvironment environment, String name) {
        final List<FxPropertyAssignment> result = Lists.newArrayList();

        // select the assignment in the root type
        final CmisVirtualProperty cmisProperty = CmisVirtualProperty.getByCmisName(name);

        final String alias = getAssignmentAlias(environment, name, cmisProperty);
        if (alias != null) {
            if (baseType.getId() == FxType.ROOT_ID
                    && ("caption".equalsIgnoreCase(alias) || "fqn".equalsIgnoreCase(alias))) {
                // caption and FQN is a special case since they are the only "real" properties that can be
                // selected from the root type
                result.addAll(
                        environment.getReferencingPropertyAssignments(environment.getProperty(alias).getId()));
            } else {
                final FxPropertyAssignment base = baseType.getPropertyAssignment("/" + alias);
                result.add(base);

                // add all derived assignments
                result.addAll(base.getDerivedAssignments(environment));
            }
        }

        return result;
    }

    private String getAssignmentAlias(FxEnvironment environment, String name, CmisVirtualProperty cmisProperty) {
        if (cmisProperty != null) {
            if (cmisProperty.getFxPropertyName() != null && cmisProperty.getFxPropertyName().charAt(0) == '@') {
                // FxSQL virtual property selected, use first read column
                return PropertyEntry.Type.createForProperty(cmisProperty.getFxPropertyName()).getReadColumns()[0];
            }
            try {
                final String assignmentXPath = "/" + name;
                baseType.getPropertyAssignment(assignmentXPath);
                // the CMIS property is already mapped in the type, ignore the CMIS mapping
                if (LOG.isDebugEnabled()) {
                    LOG.debug("CMIS property '" + name + "' is already mapped in " + baseType
                            + ", using assignment " + baseType.getPropertyAssignment(assignmentXPath).getXPath());
                }
                return name;
            } catch (FxRuntimeException e) {
                // not found, pass
            }

            // CMIS base property selected, not hidden by a flexive property assignment
            if (cmisProperty.getFxPropertyName() != null) {
                final FxProperty property = environment.getProperty(cmisProperty.getFxPropertyName());
                final List<FxPropertyAssignment> assignments = baseType.getAssignmentsForProperty(property.getId());
                return assignments.isEmpty() ? null : assignments.get(0).getAlias();
            } else {
                throw new IllegalArgumentException("Cannot select CMIS property " + name
                        + " because it is not yet mapped to the [fleXive] repository.");
            }
        } else {
            // normal flexive property assignment selected
            return name;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getIdFilterColumn() {
        return alias + "_id";
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getVersionFilterColumn() {
        return alias + "_ver";
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getIdVersionLink(String filterTableAlias, String subSelectTableAlias) {
        return "(" + filterTableAlias + "." + getIdFilterColumn() + "=" + subSelectTableAlias + ".id" + " AND "
                + filterTableAlias + "." + getVersionFilterColumn() + "=" + subSelectTableAlias + ".ver" + ")";
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<TableReference> getSubTables() {
        return new ArrayList<TableReference>(0);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Iterable<TableReference> getLeafTables() {
        return new Iterable<TableReference>() {
            @Override
            public Iterator<TableReference> iterator() {
                return Arrays.asList((TableReference) SingleTableReference.this).iterator();
            }
        };
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public FxType getRootType() {
        return baseType;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void accept(TableReferenceVisitor visitor) {
        visitor.visit(this);
    }

    @Override
    public String toString() {
        return alias;
    }

    /**
     * Escape a table alias that may be valid in CMIS SQL, but invalid in SQL92.
     *
     * @param alias the alias to be escaped
     * @return      the escaped alias
     */
    public static String escapeTableAlias(String alias) {
        return alias.replace(':', '_');
    }
}