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) {
|
||||
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(
|
||||
"webapp",
|
||||
new WebAppPatternGenerator()
|
||||
);
|
||||
// /* Register additional PatternStyleSheetResolver for Web app.
|
||||
// * With all modules installing in one context no longer required. */
|
||||
// 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