Nachhalten r2015.
git-svn-id: https://svn.libreccm.org/ccm/trunk@2037 8810af33-2d31-482b-a856-94f89814c4dfmaster
parent
f809967d30
commit
4beb75e94a
|
|
@ -48,11 +48,17 @@ public class Initializer extends CompoundInitializer {
|
||||||
public void init(DomainInitEvent evt) {
|
public void init(DomainInitEvent evt) {
|
||||||
super.init(evt);
|
super.init(evt);
|
||||||
|
|
||||||
Categorization.addCategoryListener(new TermCategoryListener());
|
// Moved to terms initializer because it is a central responsibility of
|
||||||
|
// terms itself.
|
||||||
|
// /* Create new term in the proper terms domain whenever a new category
|
||||||
|
// * is created through CMS interface, keeping both insync */
|
||||||
|
// Categorization.addCategoryListener(new TermCategoryListener());
|
||||||
|
|
||||||
PatternStylesheetResolver.registerPatternGenerator(
|
// /* Register additional PatternStyleSheetResolver for Web app.
|
||||||
"webapp",
|
// * With all modules installing in one context no longer required. */
|
||||||
new WebAppPatternGenerator()
|
// PatternStylesheetResolver.registerPatternGenerator(
|
||||||
);
|
// "webapp",
|
||||||
|
// new WebAppPatternGenerator()
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,374 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2.1 of
|
|
||||||
* the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.arsdigita.bundle;
|
|
||||||
|
|
||||||
import com.arsdigita.xml.Element;
|
|
||||||
|
|
||||||
import com.arsdigita.persistence.metadata.ObjectType;
|
|
||||||
import com.arsdigita.persistence.metadata.Property;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Stack;
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
|
|
||||||
public class ObjectTypeSchemaGenerator extends ObjectTypeTraversal {
|
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(ObjectTypeSchemaGenerator.class);
|
|
||||||
private boolean m_wrapRoot = false;
|
|
||||||
private boolean m_wrapObjects = false;
|
|
||||||
private boolean m_wrapAttributes = false;
|
|
||||||
private Stack m_history = new Stack();
|
|
||||||
private HashMap m_elements = new HashMap();
|
|
||||||
// The xs:element
|
|
||||||
private Element m_element;
|
|
||||||
// The (optional) xs:complexType
|
|
||||||
private Element m_type;
|
|
||||||
// The (optional) xs:sequence
|
|
||||||
private Element m_sequence;
|
|
||||||
// The (optional property
|
|
||||||
private Property m_property;
|
|
||||||
private Stack m_properties = new Stack();
|
|
||||||
private Element m_root;
|
|
||||||
private String m_rootName;
|
|
||||||
public static final String SCHEMA_PREFIX = "xs:";
|
|
||||||
public static final String SCHEMA_NS =
|
|
||||||
"http://www.w3.org/2001/XMLSchema";
|
|
||||||
private static HashMap s_types = new HashMap();
|
|
||||||
|
|
||||||
static {
|
|
||||||
logger.debug("Static initalizer starting...");
|
|
||||||
s_types.put(String.class, "xs:string");
|
|
||||||
s_types.put(Boolean.class, "xs:boolean");
|
|
||||||
s_types.put(Integer.class, "xs:integer");
|
|
||||||
s_types.put(BigDecimal.class, "xs:double");
|
|
||||||
logger.debug("Static initalizer finished.");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected static String lookupType(Class klass) {
|
|
||||||
if (s_types.containsKey(klass)) {
|
|
||||||
return (String) s_types.get(klass);
|
|
||||||
}
|
|
||||||
return "xs:string";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void registerType(Class klass, String type) {
|
|
||||||
s_types.put(klass, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObjectTypeSchemaGenerator(String rootName,
|
|
||||||
String namespace) {
|
|
||||||
m_root = new Element(SCHEMA_PREFIX + "schema",
|
|
||||||
SCHEMA_NS);
|
|
||||||
m_rootName = rootName;
|
|
||||||
|
|
||||||
// Set the namespace for nodes defined by the schema
|
|
||||||
m_root.addAttribute("targetNamespace", namespace);
|
|
||||||
// Set the default namespace for unqualified nodes
|
|
||||||
m_root.addAttribute("xmlns", namespace);
|
|
||||||
// All nodes in an instance doc conforming to the schema
|
|
||||||
// must be qualified
|
|
||||||
m_root.addAttribute("elementFormDefault", "qualified");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Element getRoot() {
|
|
||||||
return m_root;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines XML output for root object.
|
|
||||||
* If set to true a separate element will
|
|
||||||
* be output for the root object, if false,
|
|
||||||
* then the element passed into the constructor
|
|
||||||
* will be used.
|
|
||||||
*/
|
|
||||||
public void setWrapRoot(boolean value) {
|
|
||||||
m_wrapRoot = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines XML output used for objects.
|
|
||||||
* If set to true, then a wrapper XML element
|
|
||||||
* will be generated for the association,
|
|
||||||
* and then individual elements generated for
|
|
||||||
* each object. If false then no wrapper
|
|
||||||
* XML element will be produced.
|
|
||||||
*/
|
|
||||||
public void setWrapObjects(boolean value) {
|
|
||||||
m_wrapObjects = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines XML output used for scalar
|
|
||||||
* attributes. If set to true, then each
|
|
||||||
* attribute is output as a separate element,
|
|
||||||
* otherwise, attributes are output as simple
|
|
||||||
* attributes.
|
|
||||||
*/
|
|
||||||
public void setWrapAttributes(boolean value) {
|
|
||||||
m_wrapAttributes = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method called when the processing of an object
|
|
||||||
* starts
|
|
||||||
*/
|
|
||||||
protected void beginObject(ObjectType obj,
|
|
||||||
String path) {
|
|
||||||
// XXX deal with revisited objects - xs:choice possibly
|
|
||||||
|
|
||||||
if (m_type != null && m_sequence == null) {
|
|
||||||
Element sequence = m_type.newChildElement(SCHEMA_PREFIX + "sequence",
|
|
||||||
SCHEMA_NS);
|
|
||||||
m_sequence = sequence;
|
|
||||||
}
|
|
||||||
|
|
||||||
Element parent;
|
|
||||||
String name;
|
|
||||||
if (m_element == null) {
|
|
||||||
if (m_wrapRoot) {
|
|
||||||
Element element = m_root.newChildElement(SCHEMA_PREFIX
|
|
||||||
+ "element",
|
|
||||||
SCHEMA_NS);
|
|
||||||
element.addAttribute("name", m_rootName);
|
|
||||||
|
|
||||||
Element type = element.newChildElement(SCHEMA_PREFIX
|
|
||||||
+ "complexType",
|
|
||||||
SCHEMA_NS);
|
|
||||||
Element sequence = type.newChildElement(SCHEMA_PREFIX
|
|
||||||
+ "sequence",
|
|
||||||
SCHEMA_NS);
|
|
||||||
|
|
||||||
parent = sequence;
|
|
||||||
name = nameFromPath(path);
|
|
||||||
} else {
|
|
||||||
parent = m_root;
|
|
||||||
name = m_rootName;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
parent = m_sequence;
|
|
||||||
if (m_wrapObjects) {
|
|
||||||
name = "object";
|
|
||||||
} else {
|
|
||||||
name = nameFromPath(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Element element = parent.newChildElement(SCHEMA_PREFIX + "element",
|
|
||||||
SCHEMA_NS);
|
|
||||||
element.addAttribute("name", name);
|
|
||||||
|
|
||||||
if (m_property != null) {
|
|
||||||
if (m_property.isNullable()) {
|
|
||||||
element.addAttribute("minOccurs", "0");
|
|
||||||
}
|
|
||||||
if (m_property.isCollection()) {
|
|
||||||
element.addAttribute("maxOccurs", "unbounded");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Element type = element.newChildElement(SCHEMA_PREFIX + "complexType",
|
|
||||||
SCHEMA_NS);
|
|
||||||
|
|
||||||
Element oid = type.newChildElement(SCHEMA_PREFIX + "attribute",
|
|
||||||
SCHEMA_NS);
|
|
||||||
oid.addAttribute("name", "oid");
|
|
||||||
oid.addAttribute("type", "xs:string");
|
|
||||||
|
|
||||||
// Add to the path -> element map, not that we use this info yet
|
|
||||||
m_elements.put(path, element);
|
|
||||||
|
|
||||||
// Preserve context
|
|
||||||
m_history.push(new Element[]{m_element, m_type, m_sequence});
|
|
||||||
|
|
||||||
m_element = element;
|
|
||||||
m_type = type;
|
|
||||||
m_sequence = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method called when the procesing of an object
|
|
||||||
* completes
|
|
||||||
*/
|
|
||||||
protected void endObject(ObjectType obj,
|
|
||||||
String path) {
|
|
||||||
Element[] saved = (Element[]) m_history.pop();
|
|
||||||
m_element = saved[0];
|
|
||||||
m_type = saved[1];
|
|
||||||
m_sequence = saved[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method called when an attribute is encountered
|
|
||||||
*/
|
|
||||||
protected void handleAttribute(ObjectType obj,
|
|
||||||
String path,
|
|
||||||
Property property) {
|
|
||||||
if (m_wrapAttributes) {
|
|
||||||
if (m_sequence == null) {
|
|
||||||
Element sequence = m_type.newChildElement(SCHEMA_PREFIX
|
|
||||||
+ "sequence",
|
|
||||||
SCHEMA_NS);
|
|
||||||
m_sequence = sequence;
|
|
||||||
}
|
|
||||||
|
|
||||||
Element element = new Element(SCHEMA_PREFIX + "element",
|
|
||||||
SCHEMA_NS);
|
|
||||||
element.addAttribute("name", property.getName());
|
|
||||||
// XXX pdl type -> xs type mapping
|
|
||||||
element.addAttribute("type", lookupType(property.getJavaClass()));
|
|
||||||
|
|
||||||
if (property.isNullable()) {
|
|
||||||
element.addAttribute("minOccurs", "0");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add to element
|
|
||||||
m_sequence.addContent(element);
|
|
||||||
|
|
||||||
// Add to the path -> element map
|
|
||||||
m_elements.put(path, element);
|
|
||||||
} else {
|
|
||||||
Element element = new Element(SCHEMA_PREFIX + "attribute",
|
|
||||||
SCHEMA_NS);
|
|
||||||
element.addAttribute("name", property.getName());
|
|
||||||
// XXX pdl type -> xs type mapping
|
|
||||||
element.addAttribute("type", lookupType(property.getJavaClass()));
|
|
||||||
|
|
||||||
if (property.isRequired()) {
|
|
||||||
element.addAttribute("use", "required");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add to element
|
|
||||||
m_type.addContent(element);
|
|
||||||
|
|
||||||
// Add to the path -> element map
|
|
||||||
m_elements.put(path, element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method called when the processing of a role
|
|
||||||
* starts
|
|
||||||
*/
|
|
||||||
protected void beginRole(ObjectType obj,
|
|
||||||
String path,
|
|
||||||
Property property) {
|
|
||||||
if (m_wrapObjects) {
|
|
||||||
if (m_sequence == null) {
|
|
||||||
Element sequence = m_type.newChildElement(SCHEMA_PREFIX
|
|
||||||
+ "sequence",
|
|
||||||
SCHEMA_NS);
|
|
||||||
m_sequence = sequence;
|
|
||||||
}
|
|
||||||
|
|
||||||
Element element = m_sequence.newChildElement(SCHEMA_PREFIX
|
|
||||||
+ "element",
|
|
||||||
SCHEMA_NS);
|
|
||||||
element.addAttribute("name", property.getName());
|
|
||||||
if (property.isNullable()) {
|
|
||||||
element.addAttribute("minOccurs", "0");
|
|
||||||
}
|
|
||||||
|
|
||||||
Element type = element.newChildElement(SCHEMA_PREFIX + "complexType",
|
|
||||||
SCHEMA_NS);
|
|
||||||
Element sequence = type.newChildElement(SCHEMA_PREFIX + "sequence",
|
|
||||||
SCHEMA_NS);
|
|
||||||
|
|
||||||
// Preserve context
|
|
||||||
m_history.push(new Element[]{m_element, m_type, m_sequence});
|
|
||||||
|
|
||||||
m_element = element;
|
|
||||||
m_type = type;
|
|
||||||
m_sequence = sequence;
|
|
||||||
}
|
|
||||||
m_properties.push(m_property);
|
|
||||||
m_property = property;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method called when the procesing of a role
|
|
||||||
* completes
|
|
||||||
*/
|
|
||||||
protected void endRole(ObjectType obj,
|
|
||||||
String path,
|
|
||||||
Property property) {
|
|
||||||
if (m_wrapObjects) {
|
|
||||||
Element[] saved = (Element[]) m_history.pop();
|
|
||||||
m_element = saved[0];
|
|
||||||
m_type = saved[1];
|
|
||||||
m_sequence = saved[2];
|
|
||||||
}
|
|
||||||
m_property = (Property) m_properties.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method called when the processing of an association
|
|
||||||
* starts
|
|
||||||
*/
|
|
||||||
protected void beginAssociation(ObjectType obj,
|
|
||||||
String path,
|
|
||||||
Property property) {
|
|
||||||
if (m_wrapObjects) {
|
|
||||||
if (m_sequence == null) {
|
|
||||||
Element sequence = m_type.newChildElement(SCHEMA_PREFIX
|
|
||||||
+ "sequence",
|
|
||||||
SCHEMA_NS);
|
|
||||||
m_sequence = sequence;
|
|
||||||
}
|
|
||||||
|
|
||||||
Element element = m_sequence.newChildElement(SCHEMA_PREFIX
|
|
||||||
+ "element",
|
|
||||||
SCHEMA_NS);
|
|
||||||
element.addAttribute("name", property.getName());
|
|
||||||
if (property.isNullable()) {
|
|
||||||
element.addAttribute("minOccurs", "0");
|
|
||||||
}
|
|
||||||
|
|
||||||
Element type = element.newChildElement(SCHEMA_PREFIX + "complexType",
|
|
||||||
SCHEMA_NS);
|
|
||||||
Element sequence = type.newChildElement(SCHEMA_PREFIX + "sequence",
|
|
||||||
SCHEMA_NS);
|
|
||||||
|
|
||||||
// Preserve context
|
|
||||||
m_history.push(new Element[]{m_element, m_type, m_sequence});
|
|
||||||
|
|
||||||
m_element = element;
|
|
||||||
m_type = type;
|
|
||||||
m_sequence = sequence;
|
|
||||||
}
|
|
||||||
m_properties.push(m_property);
|
|
||||||
m_property = property;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method called when the procesing of an association
|
|
||||||
* completes
|
|
||||||
*/
|
|
||||||
protected void endAssociation(ObjectType obj,
|
|
||||||
String path,
|
|
||||||
Property property) {
|
|
||||||
if (m_wrapObjects) {
|
|
||||||
Element[] saved = (Element[]) m_history.pop();
|
|
||||||
m_element = saved[0];
|
|
||||||
m_type = saved[1];
|
|
||||||
m_sequence = saved[2];
|
|
||||||
}
|
|
||||||
m_property = (Property) m_properties.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,358 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2.1 of
|
|
||||||
* the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.arsdigita.bundle;
|
|
||||||
|
|
||||||
import com.arsdigita.util.Assert;
|
|
||||||
|
|
||||||
import com.arsdigita.persistence.metadata.ObjectType;
|
|
||||||
import com.arsdigita.persistence.metadata.Property;
|
|
||||||
import com.arsdigita.persistence.metadata.MetadataRoot;
|
|
||||||
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
|
|
||||||
// XXX this class is pretty similar to DomainObjectTraversal
|
|
||||||
// and it would be nice to figure out a way to let them share
|
|
||||||
// some of their logic (provided it didn't cripple / obfuscate
|
|
||||||
// the API).
|
|
||||||
|
|
||||||
// At minimum the process for registering & looking up hierachical
|
|
||||||
// adapters can be shared. Also the mangling of names / paths.
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>This class provides a general purpose framework for iterating
|
|
||||||
* over a domain object's properties, processing attributes and
|
|
||||||
* traversing associations as required.</p>
|
|
||||||
*
|
|
||||||
* <p>Subclasses should implement the startXXX and endXXX methods to
|
|
||||||
* provide whatever processing logic they require upon encountering
|
|
||||||
* attributes, roles, associations and objects.</p>
|
|
||||||
*
|
|
||||||
* <p>The {@link com.arsdigita.domain.ObjectTypeTraversalAdapter}
|
|
||||||
* provides a means to control which properties are processed and,
|
|
||||||
* most importantly, which associations are traversed. When
|
|
||||||
* registering an adapter, a 'use context' is supplied allowing
|
|
||||||
* different adapters to be used according to the requirements of any
|
|
||||||
* implementing subclass. It is recommended that the use context be
|
|
||||||
* based on the fully qualified name of the class using
|
|
||||||
* ObjectTypeTraversal, e.g.,
|
|
||||||
* com.arsdigita.cms.ui.ObjectTypeRenderer.</p>
|
|
||||||
*
|
|
||||||
* <p>The path argument provided to the adapter and the startXXX ad
|
|
||||||
* endXXX methods indicates which associations are currently being
|
|
||||||
* traversed. The first element in the path is always '/object'. If it
|
|
||||||
* then starts to traverse the 'rootCategory' association, the path
|
|
||||||
* will become '/object/rootCategory'. For self-recursive
|
|
||||||
* associations, rather than building up a long repeating string, the
|
|
||||||
* path will be shortened by adding a '+' for each element that is
|
|
||||||
* repeated. For example, '/object/container+' indicates that the
|
|
||||||
* container association has been followed two or more times.</p>
|
|
||||||
*/
|
|
||||||
public abstract class ObjectTypeTraversal {
|
|
||||||
|
|
||||||
private static HashMap s_adapters = new HashMap();
|
|
||||||
|
|
||||||
private static final Logger s_log = Logger.getLogger(ObjectTypeTraversal.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a traversal adapter for an object type in a given
|
|
||||||
* context.
|
|
||||||
*
|
|
||||||
* @param type the object type whose items will be traversed
|
|
||||||
* @param adapter the adapter for controlling object traversal
|
|
||||||
* @param context the context in which the adapter should be used
|
|
||||||
*/
|
|
||||||
public static void registerAdapter(ObjectType type,
|
|
||||||
ObjectTypeTraversalAdapter adapter,
|
|
||||||
String context) {
|
|
||||||
s_adapters.put(new AdapterKey(type, context), adapter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unregisteres a traversal adapter for an object type in a
|
|
||||||
* given context
|
|
||||||
*
|
|
||||||
* @param type the object type whose items will be traversed
|
|
||||||
* @param context the context in which the adapter should be used
|
|
||||||
*/
|
|
||||||
public static void unregisterAdapter(ObjectType type,
|
|
||||||
String context) {
|
|
||||||
s_adapters.remove(new AdapterKey(type, context));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Registers a traversal adapter for an object type in a given
|
|
||||||
* context.
|
|
||||||
*
|
|
||||||
* @param type the object type whose items will be traversed
|
|
||||||
* @param adapter the adapter for controlling object traversal
|
|
||||||
* @param context the context in which the adapter should be used
|
|
||||||
*/
|
|
||||||
public static void registerAdapter(String type,
|
|
||||||
ObjectTypeTraversalAdapter adapter,
|
|
||||||
String context) {
|
|
||||||
registerAdapter(MetadataRoot.getMetadataRoot().getObjectType(type),
|
|
||||||
adapter,
|
|
||||||
context);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unregisteres a traversal adapter for an object type in a
|
|
||||||
* given context
|
|
||||||
*
|
|
||||||
* @param type the object type whose items will be traversed
|
|
||||||
* @param context the context in which the adapter should be used
|
|
||||||
*/
|
|
||||||
public static void unregisterAdapter(String type,
|
|
||||||
String context) {
|
|
||||||
unregisterAdapter(MetadataRoot.getMetadataRoot().getObjectType(type),
|
|
||||||
context);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the traversal adapter for an object type in a given
|
|
||||||
* context.
|
|
||||||
*
|
|
||||||
* @param type the object type to lookup
|
|
||||||
* @param context the adapter context
|
|
||||||
*/
|
|
||||||
public static ObjectTypeTraversalAdapter lookupAdapter(ObjectType type,
|
|
||||||
String context) {
|
|
||||||
return (ObjectTypeTraversalAdapter)s_adapters
|
|
||||||
.get(new AdapterKey(type, context));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves the closest matching traversal adapter for an object type
|
|
||||||
* in a given context. The algorithm looks for an exact match, then
|
|
||||||
* considers the supertype, and the supertype's supertype. If no match
|
|
||||||
* could be found at all, returns null
|
|
||||||
*
|
|
||||||
* @param type the object type to search for
|
|
||||||
* @param context the adapter context
|
|
||||||
*/
|
|
||||||
public static ObjectTypeTraversalAdapter findAdapter(ObjectType type,
|
|
||||||
String context) {
|
|
||||||
ObjectTypeTraversalAdapter adapter = null;
|
|
||||||
while (adapter == null && type != null) {
|
|
||||||
adapter = lookupAdapter(type, context);
|
|
||||||
type = type.getSupertype();
|
|
||||||
}
|
|
||||||
return adapter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Walks over properties of a domain object, invoking
|
|
||||||
* methods to handle assoications, roles and attributes.
|
|
||||||
*
|
|
||||||
* @param obj the domain object to traverse
|
|
||||||
* @param context the context for the traversal adapter
|
|
||||||
*/
|
|
||||||
public void walk(String type,
|
|
||||||
String context) {
|
|
||||||
walk(MetadataRoot.getMetadataRoot().getObjectType(type),
|
|
||||||
context);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Walks over properties of a domain object, invoking
|
|
||||||
* methods to handle assoications, roles and attributes.
|
|
||||||
*
|
|
||||||
* @param obj the domain object to traverse
|
|
||||||
* @param context the context for the traversal adapter
|
|
||||||
*/
|
|
||||||
public void walk(ObjectType type,
|
|
||||||
String context) {
|
|
||||||
Assert.exists(type, ObjectType.class);
|
|
||||||
|
|
||||||
ObjectTypeTraversalAdapter adapter = findAdapter(type,
|
|
||||||
context);
|
|
||||||
Assert.exists(adapter, ObjectTypeTraversalAdapter.class);
|
|
||||||
walk(adapter, type, "/object");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void walk(ObjectTypeTraversalAdapter adapter,
|
|
||||||
ObjectType type,
|
|
||||||
String path) {
|
|
||||||
beginObject(type, path);
|
|
||||||
|
|
||||||
if (s_log.isInfoEnabled()) {
|
|
||||||
s_log.info("Walking " + path + " type: " + type.getQualifiedName());
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Iterator i = type.getProperties(); i.hasNext(); ) {
|
|
||||||
Property prop = (Property) i.next();
|
|
||||||
String propName = prop.getName();
|
|
||||||
|
|
||||||
if (!adapter.processProperty(type,
|
|
||||||
appendToPath(path, prop.getName()),
|
|
||||||
prop)) {
|
|
||||||
if (s_log.isDebugEnabled()) {
|
|
||||||
s_log.debug("Skipping property " + propName);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (s_log.isDebugEnabled()) {
|
|
||||||
s_log.debug("Process property " + propName + " type " + prop.getType().getQualifiedName());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prop.isAttribute()) {
|
|
||||||
handleAttribute(type, path, prop);
|
|
||||||
} else {
|
|
||||||
if (!prop.isCollection()) {
|
|
||||||
beginRole(type, path, prop);
|
|
||||||
|
|
||||||
walk(adapter,
|
|
||||||
(ObjectType)prop.getType(),
|
|
||||||
appendToPath(path, propName));
|
|
||||||
|
|
||||||
endRole(type, path, prop);
|
|
||||||
} else {
|
|
||||||
beginAssociation(type, path, prop);
|
|
||||||
|
|
||||||
Property roleProp = prop.getAssociatedProperty();
|
|
||||||
|
|
||||||
walk(adapter,
|
|
||||||
(ObjectType)prop.getType(),
|
|
||||||
appendToPath(path, propName));
|
|
||||||
|
|
||||||
endAssociation(type, path, prop);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
endObject(type, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method called when the processing of an object
|
|
||||||
* starts
|
|
||||||
*/
|
|
||||||
protected abstract void beginObject(ObjectType obj,
|
|
||||||
String path);
|
|
||||||
/**
|
|
||||||
* Method called when the procesing of an object
|
|
||||||
* completes
|
|
||||||
*/
|
|
||||||
protected abstract void endObject(ObjectType obj,
|
|
||||||
String path);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method called when an attribute is encountered
|
|
||||||
*/
|
|
||||||
protected abstract void handleAttribute(ObjectType obj,
|
|
||||||
String path,
|
|
||||||
Property property);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method called when the processing of a role
|
|
||||||
* starts
|
|
||||||
*/
|
|
||||||
protected abstract void beginRole(ObjectType obj,
|
|
||||||
String path,
|
|
||||||
Property property);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method called when the procesing of a role
|
|
||||||
* completes
|
|
||||||
*/
|
|
||||||
protected abstract void endRole(ObjectType obj,
|
|
||||||
String path,
|
|
||||||
Property property);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method called when the processing of an association
|
|
||||||
* starts
|
|
||||||
*/
|
|
||||||
protected abstract void beginAssociation(ObjectType obj,
|
|
||||||
String path,
|
|
||||||
Property property);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method called when the procesing of an association
|
|
||||||
* completes
|
|
||||||
*/
|
|
||||||
protected abstract void endAssociation(ObjectType obj,
|
|
||||||
String path,
|
|
||||||
Property property);
|
|
||||||
|
|
||||||
|
|
||||||
protected String appendToPath(String path,
|
|
||||||
String name) {
|
|
||||||
if (path.endsWith("/" + name)) {
|
|
||||||
path = path + "+";
|
|
||||||
} else if (!path.endsWith("/" + name + "+")) {
|
|
||||||
path = path + "/" + name;
|
|
||||||
}
|
|
||||||
|
|
||||||
return path;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String nameFromPath(String path) {
|
|
||||||
int index = path.lastIndexOf("/");
|
|
||||||
Assert.isTrue(index >= 0, "Path starts with /");
|
|
||||||
|
|
||||||
if (path.endsWith("+")) {
|
|
||||||
return path.substring(index + 1, path.length() - 2);
|
|
||||||
} else {
|
|
||||||
return path.substring(index + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String parentFromPath(String path) {
|
|
||||||
int index = path.lastIndexOf("/");
|
|
||||||
Assert.isTrue(index >= 0, "Path starts with /");
|
|
||||||
|
|
||||||
if (index == 0) {
|
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
return path.substring(0, index - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class AdapterKey {
|
|
||||||
private ObjectType m_type;
|
|
||||||
private String m_context;
|
|
||||||
|
|
||||||
public AdapterKey(ObjectType type,
|
|
||||||
String context) {
|
|
||||||
m_type = type;
|
|
||||||
m_context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (o instanceof AdapterKey) {
|
|
||||||
AdapterKey k = (AdapterKey)o;
|
|
||||||
return k.m_type.equals(m_type) &&
|
|
||||||
k.m_context.equals(m_context);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
|
||||||
return m_type.hashCode() + m_context.hashCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2.1 of
|
|
||||||
* the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.arsdigita.bundle;
|
|
||||||
|
|
||||||
import com.arsdigita.persistence.metadata.Property;
|
|
||||||
import com.arsdigita.persistence.metadata.ObjectType;
|
|
||||||
|
|
||||||
// XXX this class is pretty similar to DomainObjectTraversal
|
|
||||||
// and it would be nice to figure out a way to let them share
|
|
||||||
// some of their logic (provided it didn't cripple / obfuscate
|
|
||||||
// the API).
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>This interface is used to control traversal of domain
|
|
||||||
* objects. Whenever a property is encountered, the {@link
|
|
||||||
* #processProperty} method will be called to determine whether or not
|
|
||||||
* to continue processing the object. The most important use for this
|
|
||||||
* is to prevent the needless (and potentially infinite) traversal of
|
|
||||||
* associations between objects, but it can also be used to filter out
|
|
||||||
* certain attributes.</p>
|
|
||||||
*
|
|
||||||
* <p>Instances of this class need to be registered using the
|
|
||||||
* DomainObjectTraversal.registerAdapter method.</p>
|
|
||||||
*
|
|
||||||
* @see com.arsdigita.domain.DomainObjectTraversal
|
|
||||||
* @see com.arsdigita.domain.SimpleDomainObjectTraversalAdapter
|
|
||||||
* @version $Id: ObjectTypeTraversalAdapter.java 287 2005-02-22 00:29:02Z sskracic $
|
|
||||||
*/
|
|
||||||
public interface ObjectTypeTraversalAdapter {
|
|
||||||
/**
|
|
||||||
* Invoked to determine whether to process a property.
|
|
||||||
* Should return true to allow processing to commence,
|
|
||||||
* false to prevent it.
|
|
||||||
*
|
|
||||||
* @param obj the object type currently being processed
|
|
||||||
* @param path the path to the current domain object from
|
|
||||||
* the root object being traversed
|
|
||||||
* @param prop the property about to be processed
|
|
||||||
* @return true if the property should be processed
|
|
||||||
*/
|
|
||||||
public boolean processProperty(ObjectType obj,
|
|
||||||
String path,
|
|
||||||
Property prop);
|
|
||||||
}
|
|
||||||
|
|
@ -1,151 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2.1 of
|
|
||||||
* the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.arsdigita.bundle;
|
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import com.arsdigita.persistence.metadata.Property;
|
|
||||||
import com.arsdigita.persistence.metadata.ObjectType;
|
|
||||||
import java.util.HashSet;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is a general purpose traversal adaptor
|
|
||||||
* that allows/denies processing of a property
|
|
||||||
* based on the path to the property, and its
|
|
||||||
* presence in an inclusion/exclusion set.
|
|
||||||
*
|
|
||||||
* Instances of this class can be configured using
|
|
||||||
* the ObjectTypeTraversalInitializer
|
|
||||||
*
|
|
||||||
* <p>See <code>com.arsdigita.cms.installer.ObjectTypeTraversalInitializer</code>.
|
|
||||||
*/
|
|
||||||
public class SimpleObjectTypeTraversalAdapter
|
|
||||||
implements ObjectTypeTraversalAdapter {
|
|
||||||
|
|
||||||
private static final Logger s_log =
|
|
||||||
Logger.getLogger(SimpleObjectTypeTraversalAdapter.class);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Rule that indicates the set of properties should be treated
|
|
||||||
* as an inclusion list. ie, don't allow any properties except
|
|
||||||
* those listed. This is the default for associations
|
|
||||||
*/
|
|
||||||
public final static int RULE_INCLUDE = 0;
|
|
||||||
/**
|
|
||||||
* Rule that indicates the set of properties should be treated
|
|
||||||
* as an exclusion list. ie, allow through all properties,
|
|
||||||
* except those listed. This is the default for attributes.
|
|
||||||
*/
|
|
||||||
public final static int RULE_EXCLUDE = 1;
|
|
||||||
|
|
||||||
private HashSet m_attr = new HashSet();
|
|
||||||
private HashSet m_assoc = new HashSet();
|
|
||||||
|
|
||||||
private int m_attrRule = RULE_EXCLUDE;
|
|
||||||
private int m_assocRule = RULE_INCLUDE;
|
|
||||||
|
|
||||||
private SimpleObjectTypeTraversalAdapter m_parent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new traversal adapter, with no parent
|
|
||||||
* delegate. If no explicit rule is present it will
|
|
||||||
* return false if RULE_INCLUDE is set, or true if
|
|
||||||
* RULE_EXCLUDE is set.
|
|
||||||
*/
|
|
||||||
public SimpleObjectTypeTraversalAdapter() {
|
|
||||||
this(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new traversal adapter, extending the rules
|
|
||||||
* defined by a parent. If there is no explicit rule
|
|
||||||
* for the property questioned, it will delegate the
|
|
||||||
* query to the parent.
|
|
||||||
* @param parent the parent adapter to delegate to
|
|
||||||
*/
|
|
||||||
public SimpleObjectTypeTraversalAdapter(
|
|
||||||
SimpleObjectTypeTraversalAdapter parent
|
|
||||||
) {
|
|
||||||
m_parent = parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the rule for processing attributes
|
|
||||||
*
|
|
||||||
* @param rule the new processing rule
|
|
||||||
*/
|
|
||||||
public void setAttributeRule(int rule) {
|
|
||||||
m_attrRule = rule;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the rule for processing associations
|
|
||||||
*
|
|
||||||
* @param rule the new processing rule
|
|
||||||
*/
|
|
||||||
public void setAssociationRule(int rule) {
|
|
||||||
m_assocRule = rule;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a property to the attribute property set.
|
|
||||||
*
|
|
||||||
* @param path the full path to the property
|
|
||||||
*/
|
|
||||||
public void addAttributeProperty(String prop) {
|
|
||||||
m_attr.add(prop);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a property to the association property set.
|
|
||||||
*
|
|
||||||
* @param path the full path to the property
|
|
||||||
*/
|
|
||||||
public void addAssociationProperty(String prop) {
|
|
||||||
m_assoc.add(prop);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether or not to allow processing
|
|
||||||
* of a property, based on the property set and
|
|
||||||
* the processing rule
|
|
||||||
*/
|
|
||||||
public boolean processProperty(ObjectType obj,
|
|
||||||
String path,
|
|
||||||
Property prop) {
|
|
||||||
if (prop.isAttribute()) {
|
|
||||||
boolean result = m_attr.contains(path);
|
|
||||||
s_log.debug("Check attr " + path + " contains " +
|
|
||||||
result + " " + m_attrRule);
|
|
||||||
if (!result && m_parent != null) {
|
|
||||||
s_log.debug("No explicit rule, delegating to parent");
|
|
||||||
return m_parent.processProperty(obj, path, prop);
|
|
||||||
}
|
|
||||||
return m_attrRule == RULE_INCLUDE ? result : !result;
|
|
||||||
} else {
|
|
||||||
boolean result = m_assoc.contains(path);
|
|
||||||
s_log.debug("Check assoc " + path + " contains " +
|
|
||||||
result + " " + m_attrRule);
|
|
||||||
if (!result && m_parent != null) {
|
|
||||||
s_log.debug("No explicit rule, delegating to parent");
|
|
||||||
return m_parent.processProperty(obj, path, prop);
|
|
||||||
}
|
|
||||||
return m_assocRule == RULE_INCLUDE ? result : !result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,57 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2.1 of
|
|
||||||
* the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.arsdigita.bundle;
|
|
||||||
|
|
||||||
|
|
||||||
import com.arsdigita.web.Application;
|
|
||||||
import com.arsdigita.web.Web;
|
|
||||||
import com.arsdigita.templating.PatternGenerator;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a set of patterns corresponding to the current
|
|
||||||
* web application prefix
|
|
||||||
*/
|
|
||||||
public class WebAppPatternGenerator implements PatternGenerator {
|
|
||||||
|
|
||||||
private static final Logger s_log =
|
|
||||||
Logger.getLogger(WebAppPatternGenerator.class);
|
|
||||||
|
|
||||||
public String[] generateValues(String key,
|
|
||||||
HttpServletRequest req) {
|
|
||||||
Application app = Web.getContext().getApplication();
|
|
||||||
String ctx = app == null ? null : app.getContextPath();
|
|
||||||
|
|
||||||
if (app == null ||
|
|
||||||
ctx == null ||
|
|
||||||
"".equals(ctx)) {
|
|
||||||
return new String[] { Web.ROOT_WEBAPP };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ctx.startsWith("/")) {
|
|
||||||
ctx = ctx.substring(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new String[] { ctx };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue