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

org.objectstyle.cayenne.project.ProjectTraversal Maven / Gradle / Ivy

There is a newer version: 1.2.4
Show newest version
/* ====================================================================
 * 
 * The ObjectStyle Group Software License, version 1.1
 * ObjectStyle Group - http://objectstyle.org/
 * 
 * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
 * of the software. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 
 * 3. The end-user documentation included with the redistribution, if any,
 *    must include the following acknowlegement:
 *    "This product includes software developed by independent contributors
 *    and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 * 
 * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
 *    or promote products derived from this software without prior written
 *    permission. For written permission, email
 *    "andrus at objectstyle dot org".
 * 
 * 5. Products derived from this software may not be called "ObjectStyle"
 *    or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
 *    names without prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 * 
 * This software consists of voluntary contributions made by many
 * individuals and hosted on ObjectStyle Group web site.  For more
 * information on the ObjectStyle Group, please see
 * .
 */
package org.objectstyle.cayenne.project;

import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;

import org.objectstyle.cayenne.access.DataDomain;
import org.objectstyle.cayenne.access.DataNode;
import org.objectstyle.cayenne.map.Attribute;
import org.objectstyle.cayenne.map.DataMap;
import org.objectstyle.cayenne.map.Entity;
import org.objectstyle.cayenne.map.Procedure;
import org.objectstyle.cayenne.map.Relationship;
import org.objectstyle.cayenne.query.Query;
import org.objectstyle.cayenne.util.CayenneMapEntry;
import org.objectstyle.cayenne.util.Util;

/**
 * ProjectTraversal allows to traverse Cayenne project tree in a "depth-first" order
 * starting from an arbitrary level to its children.
 * 

* Current implementation is not very efficient and would actually first read the whole * tree, before returning the first element from the iterator. *

* * @author Andrei Adamchik */ public class ProjectTraversal { protected static final Comparator mapObjectComparator = new MapObjectComparator(); protected static final Comparator dataMapComparator = new DataMapComparator(); protected static final Comparator dataDomainComparator = new DataDomainComparator(); protected static final Comparator dataNodeComparator = new DataNodeComparator(); protected static final Comparator queryComparator = new QueryComparator(); protected ProjectTraversalHandler handler; protected boolean sort; public ProjectTraversal(ProjectTraversalHandler handler) { this(handler, false); } /** * Creates ProjectTraversal instance with a given handler and sort policy. If * sort is true, children of each node will be sorted using a * predefined Comparator for a given type of child nodes. */ public ProjectTraversal(ProjectTraversalHandler handler, boolean sort) { this.handler = handler; this.sort = sort; } /** * Performs traversal starting from the root node. Root node can be of any type * supported in Cayenne projects (Configuration, DataMap, DataNode, etc...) */ public void traverse(Object rootNode) { this.traverse(rootNode, new ProjectPath()); } public void traverse(Object rootNode, ProjectPath path) { if (rootNode instanceof Project) { this.traverseProject((Project) rootNode, path); } else if (rootNode instanceof DataDomain) { this.traverseDomains(Collections.singletonList(rootNode).iterator(), path); } else if (rootNode instanceof DataMap) { this.traverseMaps(Collections.singletonList(rootNode).iterator(), path); } else if (rootNode instanceof Entity) { this.traverseEntities(Collections.singletonList(rootNode).iterator(), path); } else if (rootNode instanceof Attribute) { this.traverseAttributes(Collections.singletonList(rootNode).iterator(), path); } else if (rootNode instanceof Relationship) { this.traverseRelationships( Collections.singletonList(rootNode).iterator(), path); } else if (rootNode instanceof DataNode) { this.traverseNodes(Collections.singletonList(rootNode).iterator(), path); } else { String nodeClass = (rootNode != null) ? rootNode.getClass().getName() : "(null)"; throw new IllegalArgumentException("Unsupported root node: " + nodeClass); } } /** * Performs traversal starting from the Project and down to its children. */ public void traverseProject(Project project, ProjectPath path) { ProjectPath projectPath = path.appendToPath(project); handler.projectNode(projectPath); if (handler.shouldReadChildren(project, path)) { Iterator it = project.getChildren().iterator(); while (it.hasNext()) { this.traverse(it.next(), projectPath); } } } /** * Performs traversal starting from a list of domains. */ public void traverseDomains(Iterator domains, ProjectPath path) { if (sort) { domains = Util.sortedIterator(domains, ProjectTraversal.dataDomainComparator); } while (domains.hasNext()) { DataDomain domain = (DataDomain) domains.next(); ProjectPath domainPath = path.appendToPath(domain); handler.projectNode(domainPath); if (handler.shouldReadChildren(domain, path)) { this.traverseMaps(domain.getDataMaps().iterator(), domainPath); this.traverseNodes(domain.getDataNodes().iterator(), domainPath); } } } public void traverseNodes(Iterator nodes, ProjectPath path) { if (sort) { nodes = Util.sortedIterator(nodes, ProjectTraversal.dataNodeComparator); } while (nodes.hasNext()) { DataNode node = (DataNode) nodes.next(); ProjectPath nodePath = path.appendToPath(node); handler.projectNode(nodePath); if (handler.shouldReadChildren(node, path)) { this.traverseMaps(node.getDataMaps().iterator(), nodePath); } } } public void traverseMaps(Iterator maps, ProjectPath path) { if (sort) { maps = Util.sortedIterator(maps, ProjectTraversal.dataMapComparator); } while (maps.hasNext()) { DataMap map = (DataMap) maps.next(); ProjectPath mapPath = path.appendToPath(map); handler.projectNode(mapPath); if (handler.shouldReadChildren(map, path)) { this.traverseEntities(map.getObjEntities().iterator(), mapPath); this.traverseEntities(map.getDbEntities().iterator(), mapPath); this.traverseProcedures(map.getProcedures().iterator(), mapPath); this.traverseQueries(map.getQueries().iterator(), mapPath); } } } /** * Performs recursive traversal of an Iterator of Cayenne Query objects. */ public void traverseQueries(Iterator queries, ProjectPath path) { if (sort) { queries = Util.sortedIterator(queries, ProjectTraversal.queryComparator); } while (queries.hasNext()) { Query query = (Query) queries.next(); ProjectPath queryPath = path.appendToPath(query); handler.projectNode(queryPath); } } /** * Performs recusrive traversal of an Iterator of Cayenne Procedure objects. */ public void traverseProcedures(Iterator procedures, ProjectPath path) { if (sort) { procedures = Util.sortedIterator( procedures, ProjectTraversal.mapObjectComparator); } while (procedures.hasNext()) { Procedure procedure = (Procedure) procedures.next(); ProjectPath procedurePath = path.appendToPath(procedure); handler.projectNode(procedurePath); if (handler.shouldReadChildren(procedure, path)) { this.traverseProcedureParameters( procedure.getCallParameters().iterator(), procedurePath); } } } public void traverseEntities(Iterator entities, ProjectPath path) { if (sort) { entities = Util .sortedIterator(entities, ProjectTraversal.mapObjectComparator); } while (entities.hasNext()) { Entity ent = (Entity) entities.next(); ProjectPath entPath = path.appendToPath(ent); handler.projectNode(entPath); if (handler.shouldReadChildren(ent, path)) { this.traverseAttributes(ent.getAttributes().iterator(), entPath); this.traverseRelationships(ent.getRelationships().iterator(), entPath); } } } public void traverseAttributes(Iterator attributes, ProjectPath path) { if (sort) { attributes = Util.sortedIterator( attributes, ProjectTraversal.mapObjectComparator); } while (attributes.hasNext()) { handler.projectNode(path.appendToPath(attributes.next())); } } public void traverseRelationships(Iterator relationships, ProjectPath path) { if (sort) { relationships = Util.sortedIterator( relationships, ProjectTraversal.mapObjectComparator); } while (relationships.hasNext()) { handler.projectNode(path.appendToPath(relationships.next())); } } public void traverseProcedureParameters(Iterator parameters, ProjectPath path) { // Note: !! do not try to sort parameters - they are positional by definition while (parameters.hasNext()) { handler.projectNode(path.appendToPath(parameters.next())); } } static class QueryComparator implements Comparator { public int compare(Object o1, Object o2) { String name1 = ((Query) o1).getName(); String name2 = ((Query) o2).getName(); if (name1 == null) { return (name2 != null) ? -1 : 0; } else if (name2 == null) { return 1; } else { return name1.compareTo(name2); } } } static class MapObjectComparator implements Comparator { public int compare(Object o1, Object o2) { String name1 = ((CayenneMapEntry) o1).getName(); String name2 = ((CayenneMapEntry) o2).getName(); if (name1 == null) { return (name2 != null) ? -1 : 0; } else if (name2 == null) { return 1; } else { return name1.compareTo(name2); } } } static class DataMapComparator implements Comparator { public int compare(Object o1, Object o2) { String name1 = ((DataMap) o1).getName(); String name2 = ((DataMap) o2).getName(); if (name1 == null) { return (name2 != null) ? -1 : 0; } else if (name2 == null) { return 1; } else { return name1.compareTo(name2); } } } static class DataDomainComparator implements Comparator { public int compare(Object o1, Object o2) { String name1 = ((DataDomain) o1).getName(); String name2 = ((DataDomain) o2).getName(); if (name1 == null) { return (name2 != null) ? -1 : 0; } else if (name2 == null) { return 1; } else { return name1.compareTo(name2); } } } static class DataNodeComparator implements Comparator { public int compare(Object o1, Object o2) { String name1 = ((DataNode) o1).getName(); String name2 = ((DataNode) o2).getName(); if (name1 == null) { return (name2 != null) ? -1 : 0; } else if (name2 == null) { return 1; } else { return name1.compareTo(name2); } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy