001: package org.compass.core.converter.dynamic;
002:
003: import java.lang.reflect.Array;
004: import java.util.Collection;
005: import java.util.Iterator;
006:
007: import org.compass.core.Property;
008: import org.compass.core.Resource;
009: import org.compass.core.converter.ConversionException;
010: import org.compass.core.converter.basic.AbstractBasicConverter;
011: import org.compass.core.converter.basic.FormatConverter;
012: import org.compass.core.mapping.Mapping;
013: import org.compass.core.mapping.ResourcePropertyMapping;
014: import org.compass.core.marshall.MarshallingContext;
015:
016: /**
017: * A simple base class for {@link DynamicConverter}. Requires implementation of
018: * {@link #evaluate(Object,org.compass.core.mapping.ResourcePropertyMapping)}.
019: *
020: * <p>Also holds a {@link FormatConverter} for expression that return formatable
021: * objects (like Date).
022: *
023: * @author kimchy
024: */
025: public abstract class AbstractDynamicConverter extends
026: AbstractBasicConverter implements DynamicConverter {
027:
028: private FormatConverter formatConverter;
029:
030: private Class type;
031:
032: public DynamicConverter copy() {
033: try {
034: DynamicConverter converter = (DynamicConverter) getClass()
035: .newInstance();
036: converter.setType(getType());
037: converter.setFormatConverter(formatConverter);
038: return converter;
039: } catch (Exception e) {
040: throw new ConversionException("This should not happen", e);
041: }
042: }
043:
044: public void setFormatConverter(FormatConverter formatConverter) {
045: this .formatConverter = formatConverter;
046: }
047:
048: public boolean marshall(Resource resource, Object root,
049: Mapping mapping, MarshallingContext context)
050: throws ConversionException {
051:
052: ResourcePropertyMapping resourcePropertyMapping = (ResourcePropertyMapping) mapping;
053:
054: if (root == null) {
055: return false;
056: }
057: Object value = evaluate(root, resourcePropertyMapping);
058: if (value == null) {
059: if (resourcePropertyMapping.hasNullValue()) {
060: addProperty(resourcePropertyMapping.getNullValue(),
061: resourcePropertyMapping, root, context,
062: resource);
063: }
064: return false;
065: }
066: // save the value in the search engine. Handle array/collection and single values
067: if (value.getClass().isArray()) {
068: int length = Array.getLength(value);
069: for (int i = 0; i < length; i++) {
070: addProperty(Array.get(value, i),
071: resourcePropertyMapping, root, context,
072: resource);
073: }
074: } else if (value instanceof Collection) {
075: Collection colValues = (Collection) value;
076: for (Iterator it = colValues.iterator(); it.hasNext();) {
077: addProperty(it.next(), resourcePropertyMapping, root,
078: context, resource);
079: }
080: } else {
081: addProperty(value, resourcePropertyMapping, root, context,
082: resource);
083: }
084: return resourcePropertyMapping.getStore() != Property.Store.NO;
085: }
086:
087: protected void addProperty(Object value,
088: ResourcePropertyMapping resourcePropertyMapping,
089: Object root, MarshallingContext context, Resource resource) {
090: String sValue;
091: if (formatConverter == null) {
092: sValue = value.toString();
093: } else {
094: sValue = formatConverter.toString(value,
095: resourcePropertyMapping);
096: }
097: addProperty(sValue, resourcePropertyMapping, root, context,
098: resource);
099: }
100:
101: private void addProperty(String value,
102: ResourcePropertyMapping resourcePropertyMapping,
103: Object root, MarshallingContext context, Resource resource) {
104: Property p = context.getResourceFactory().createProperty(value,
105: resourcePropertyMapping);
106: doSetBoost(p, root, resourcePropertyMapping, context);
107: resource.addProperty(p);
108: }
109:
110: /**
111: * Evaluates the given data object using the configured expression.
112: *
113: * @param o The data object
114: * @param resourcePropertyMapping The resource mapping
115: * @return The object returned as a result of expression evaluation
116: * @throws ConversionException
117: */
118: protected abstract Object evaluate(Object o,
119: ResourcePropertyMapping resourcePropertyMapping)
120: throws ConversionException;
121:
122: /**
123: * Does nothing since there is no meaning for un-marshalling for dynamic converters
124: */
125: public Object unmarshall(Resource resource, Mapping mapping,
126: MarshallingContext context) throws ConversionException {
127: // nothing to do here
128: return null;
129: }
130:
131: /**
132: * Does nothing since there is no meaning for un-marshalling for dynamic converters
133: */
134: protected Object doFromString(String str,
135: ResourcePropertyMapping resourcePropertyMapping,
136: MarshallingContext context) throws ConversionException {
137: // do nothing here
138: return null;
139: }
140:
141: public Class getType() {
142: return type;
143: }
144:
145: public void setType(Class type) {
146: this.type = type;
147: }
148: }
|