0001: /*
0002: * Copyright 2004-2006 the original author or authors.
0003: *
0004: * Licensed under the Apache License, Version 2.0 (the "License");
0005: * you may not use this file except in compliance with the License.
0006: * You may obtain a copy of the License at
0007: *
0008: * http://www.apache.org/licenses/LICENSE-2.0
0009: *
0010: * Unless required by applicable law or agreed to in writing, software
0011: * distributed under the License is distributed on an "AS IS" BASIS,
0012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013: * See the License for the specific language governing permissions and
0014: * limitations under the License.
0015: */
0016:
0017: package org.compass.annotations.config.binding;
0018:
0019: import java.lang.annotation.Annotation;
0020: import java.lang.reflect.AnnotatedElement;
0021: import java.lang.reflect.Field;
0022: import java.lang.reflect.Method;
0023: import java.lang.reflect.Modifier;
0024: import java.lang.reflect.Type;
0025: import java.util.ArrayList;
0026: import java.util.Arrays;
0027: import java.util.StringTokenizer;
0028:
0029: import org.apache.commons.logging.Log;
0030: import org.apache.commons.logging.LogFactory;
0031: import org.apache.lucene.analysis.Analyzer;
0032: import org.compass.annotations.*;
0033: import org.compass.core.config.CommonMetaDataLookup;
0034: import org.compass.core.config.CompassConfigurable;
0035: import org.compass.core.config.CompassEnvironment;
0036: import org.compass.core.config.CompassSettings;
0037: import org.compass.core.config.ConfigurationException;
0038: import org.compass.core.config.binding.MappingBindingSupport;
0039: import org.compass.core.converter.Converter;
0040: import org.compass.core.converter.mapping.osem.MetaDataFormatDelegateConverter;
0041: import org.compass.core.engine.naming.StaticPropertyPath;
0042: import org.compass.core.engine.subindex.ConstantSubIndexHash;
0043: import org.compass.core.engine.subindex.SubIndexHash;
0044: import org.compass.core.lucene.LuceneEnvironment;
0045: import org.compass.core.mapping.AliasMapping;
0046: import org.compass.core.mapping.CascadeMapping;
0047: import org.compass.core.mapping.CompassMapping;
0048: import org.compass.core.mapping.Mapping;
0049: import org.compass.core.mapping.MappingException;
0050: import org.compass.core.mapping.SpellCheckType;
0051: import org.compass.core.mapping.internal.DefaultAllMapping;
0052: import org.compass.core.mapping.internal.InternalResourcePropertyMapping;
0053: import org.compass.core.mapping.osem.ClassBoostPropertyMapping;
0054: import org.compass.core.mapping.osem.ClassIdPropertyMapping;
0055: import org.compass.core.mapping.osem.ClassMapping;
0056: import org.compass.core.mapping.osem.ClassPropertyAnalyzerController;
0057: import org.compass.core.mapping.osem.ClassPropertyMapping;
0058: import org.compass.core.mapping.osem.ClassPropertyMetaDataMapping;
0059: import org.compass.core.mapping.osem.ComponentMapping;
0060: import org.compass.core.mapping.osem.ConstantMetaDataMapping;
0061: import org.compass.core.mapping.osem.DynamicMetaDataMapping;
0062: import org.compass.core.mapping.osem.IdComponentMapping;
0063: import org.compass.core.mapping.osem.ObjectMapping;
0064: import org.compass.core.mapping.osem.ParentMapping;
0065: import org.compass.core.mapping.osem.PlainCascadeMapping;
0066: import org.compass.core.mapping.osem.ReferenceMapping;
0067: import org.compass.core.metadata.Alias;
0068: import org.compass.core.metadata.CompassMetaData;
0069: import org.compass.core.util.ClassUtils;
0070: import org.compass.core.util.StringUtils;
0071:
0072: /**
0073: * @author kimchy
0074: */
0075: public class AnnotationsMappingBinding extends MappingBindingSupport {
0076:
0077: public static final Log log = LogFactory
0078: .getLog(AnnotationsMappingBinding.class);
0079:
0080: private CommonMetaDataLookup valueLookup;
0081:
0082: private CompassMapping mapping;
0083:
0084: private ClassMapping classMapping;
0085:
0086: private CompassSettings settings;
0087:
0088: public void setUpBinding(CompassMapping mapping,
0089: CompassMetaData metaData, CompassSettings settings) {
0090: this .mapping = mapping;
0091: this .valueLookup = new CommonMetaDataLookup(metaData);
0092: this .settings = settings;
0093: }
0094:
0095: public boolean addPackage(String packageName)
0096: throws ConfigurationException, MappingException {
0097: Package pckg;
0098: try {
0099: pckg = ClassUtils.forName(packageName + ".package-info",
0100: settings.getClassLoader()).getPackage();
0101: } catch (ClassNotFoundException e) {
0102: return false;
0103: }
0104: if (pckg.isAnnotationPresent(SearchConverter.class)) {
0105: bindConverter(pckg.getAnnotation(SearchConverter.class));
0106: }
0107: if (pckg.isAnnotationPresent(SearchConverters.class)) {
0108: SearchConverters searchConverters = pckg
0109: .getAnnotation(SearchConverters.class);
0110: for (SearchConverter searchConverter : searchConverters
0111: .value()) {
0112: bindConverter(searchConverter);
0113: }
0114: }
0115: if (pckg.isAnnotationPresent(SearchAnalyzer.class)) {
0116: bindAnalyzer(pckg.getAnnotation(SearchAnalyzer.class));
0117: }
0118: if (pckg.isAnnotationPresent(SearchAnalyzers.class)) {
0119: SearchAnalyzers searchAnalyzers = pckg
0120: .getAnnotation(SearchAnalyzers.class);
0121: for (SearchAnalyzer searchAnalyzer : searchAnalyzers
0122: .value()) {
0123: bindAnalyzer(searchAnalyzer);
0124: }
0125: }
0126: if (pckg.isAnnotationPresent(SearchAnalyzerFilter.class)) {
0127: bindAnalyzerFilter(pckg
0128: .getAnnotation(SearchAnalyzerFilter.class));
0129: }
0130: if (pckg.isAnnotationPresent(SearchAnalyzerFilters.class)) {
0131: SearchAnalyzerFilters searchAnalyzerFilters = pckg
0132: .getAnnotation(SearchAnalyzerFilters.class);
0133: for (SearchAnalyzerFilter searchAnalyzerFilter : searchAnalyzerFilters
0134: .value()) {
0135: bindAnalyzerFilter(searchAnalyzerFilter);
0136: }
0137: }
0138: return true;
0139: }
0140:
0141: private void bindAnalyzerFilter(
0142: SearchAnalyzerFilter searchAnalyzerFilter)
0143: throws ConfigurationException, MappingException {
0144: ArrayList<String> settingsNames = new ArrayList<String>();
0145: ArrayList<String> settingsValues = new ArrayList<String>();
0146: settingsNames.add(LuceneEnvironment.AnalyzerFilter.TYPE);
0147: settingsValues.add(searchAnalyzerFilter.type().getName());
0148:
0149: for (SearchSetting setting : searchAnalyzerFilter.settings()) {
0150: settingsNames.add(setting.name());
0151: settingsValues.add(setting.value());
0152: }
0153:
0154: settings.setGroupSettings(
0155: LuceneEnvironment.AnalyzerFilter.PREFIX,
0156: searchAnalyzerFilter.name(), settingsNames
0157: .toArray(new String[settingsNames.size()]),
0158: settingsValues
0159: .toArray(new String[settingsValues.size()]));
0160: }
0161:
0162: private void bindAnalyzer(SearchAnalyzer searchAnalyzer)
0163: throws ConfigurationException, MappingException {
0164: ArrayList<String> settingsNames = new ArrayList<String>();
0165: ArrayList<String> settingsValues = new ArrayList<String>();
0166:
0167: settingsNames.add(LuceneEnvironment.Analyzer.TYPE);
0168: if (searchAnalyzer.type() == AnalyzerType.CustomAnalyzer) {
0169: if (Analyzer.class.equals(searchAnalyzer.analyzerClass())) {
0170: throw new ConfigurationException("SearchableAnalyzer ["
0171: + searchAnalyzer.name() + "] has "
0172: + "type of [" + AnalyzerType.CustomAnalyzer
0173: + "] but does not set analyzerClass");
0174: }
0175: settingsValues
0176: .add(searchAnalyzer.analyzerClass().getName());
0177: } else {
0178: settingsValues.add(searchAnalyzer.type().toString());
0179: }
0180:
0181: if (searchAnalyzer.type() == AnalyzerType.Snowball) {
0182: settingsNames
0183: .add(LuceneEnvironment.Analyzer.Snowball.NAME_TYPE);
0184: settingsValues
0185: .add(searchAnalyzer.snowballType().toString());
0186: }
0187:
0188: if (searchAnalyzer.stopWords().length > 0) {
0189: StringBuffer sb = new StringBuffer();
0190: if (searchAnalyzer.addStopWords()) {
0191: sb.append("+");
0192: }
0193: for (String stopword : searchAnalyzer.stopWords()) {
0194: sb.append(stopword).append(",");
0195: }
0196: settingsNames.add(LuceneEnvironment.Analyzer.STOPWORDS);
0197: settingsValues.add(sb.toString());
0198: }
0199:
0200: if (searchAnalyzer.filters().length > 0) {
0201: StringBuffer sb = new StringBuffer();
0202: for (String filter : searchAnalyzer.filters()) {
0203: sb.append(filter).append(",");
0204: }
0205: settingsNames.add(LuceneEnvironment.Analyzer.FILTERS);
0206: settingsValues.add(sb.toString());
0207: }
0208:
0209: for (SearchSetting setting : searchAnalyzer.settings()) {
0210: settingsNames.add(setting.name());
0211: settingsValues.add(setting.value());
0212: }
0213:
0214: settings.setGroupSettings(LuceneEnvironment.Analyzer.PREFIX,
0215: searchAnalyzer.name(), settingsNames
0216: .toArray(new String[settingsNames.size()]),
0217: settingsValues
0218: .toArray(new String[settingsValues.size()]));
0219: }
0220:
0221: private void bindConverter(SearchConverter searchConverter)
0222: throws ConfigurationException, MappingException {
0223: String[] settingsNames = new String[searchConverter.settings().length + 1];
0224: String[] settingsValues = new String[searchConverter.settings().length + 1];
0225: int i = 0;
0226: for (; i < searchConverter.settings().length; i++) {
0227: SearchSetting setting = searchConverter.settings()[i];
0228: settingsNames[i] = setting.name();
0229: settingsValues[i] = setting.value();
0230: }
0231: settingsNames[i] = CompassEnvironment.Converter.TYPE;
0232: settingsValues[i] = searchConverter.type().getName();
0233: settings.setGroupSettings(CompassEnvironment.Converter.PREFIX,
0234: searchConverter.name(), settingsNames, settingsValues);
0235: }
0236:
0237: public boolean addClass(Class clazz) throws ConfigurationException,
0238: MappingException {
0239: Class<?> annotationClass = clazz;
0240: Searchable searchable = annotationClass
0241: .getAnnotation(Searchable.class);
0242: if (searchable == null) {
0243: return false;
0244: }
0245: String alias = getAliasFromSearchableClass(clazz, searchable);
0246: // try and check is the class mapping is already defined
0247: // if it is, we will add mapping definitions on top of it
0248: boolean newClassMapping = false;
0249: AliasMapping aliasMapping = mapping.getAliasMapping(alias);
0250: if (aliasMapping != null) {
0251: if (!(aliasMapping instanceof ClassMapping)) {
0252: throw new MappingException(
0253: "Defined searchable annotation on a class with alias ["
0254: + alias
0255: + "] which"
0256: + " has other mapping definitions, but it not of type class mapping");
0257: }
0258: classMapping = (ClassMapping) aliasMapping;
0259: } else {
0260: classMapping = new ClassMapping();
0261: newClassMapping = true;
0262: }
0263: classMapping.setAlias(alias);
0264:
0265: classMapping.setName(clazz.getName());
0266: classMapping.setClazz(clazz);
0267:
0268: // sub index (including hash support)
0269: String subIndex = searchable.subIndex();
0270: if (!StringUtils.hasLength(subIndex)) {
0271: subIndex = alias;
0272: }
0273: SearchableSubIndexHash searchableSubIndexHash = annotationClass
0274: .getAnnotation(SearchableSubIndexHash.class);
0275: if (searchableSubIndexHash == null) {
0276: classMapping.setSubIndexHash(new ConstantSubIndexHash(
0277: subIndex));
0278: } else {
0279: SubIndexHash subIndexHash;
0280: try {
0281: subIndexHash = searchableSubIndexHash.value()
0282: .newInstance();
0283: } catch (Exception e) {
0284: throw new MappingException(
0285: "Failed to create sub index hash ["
0286: + searchableSubIndexHash.value()
0287: .getName() + "]", e);
0288: }
0289: if (subIndexHash instanceof CompassConfigurable) {
0290: CompassSettings settings = new CompassSettings();
0291: for (int i = 0; i < searchableSubIndexHash.settings().length; i++) {
0292: SearchSetting setting = searchableSubIndexHash
0293: .settings()[i];
0294: settings
0295: .setSetting(setting.name(), setting.value());
0296: }
0297: ((CompassConfigurable) subIndexHash)
0298: .configure(settings);
0299: }
0300: classMapping.setSubIndexHash(subIndexHash);
0301: }
0302: if (log.isTraceEnabled()) {
0303: log.trace("Alias [" + classMapping.getAlias()
0304: + "] is mapped to sub index hash ["
0305: + classMapping.getSubIndexHash() + "]");
0306: }
0307:
0308: DefaultAllMapping allMapping = new DefaultAllMapping();
0309: SearchableAllMetaData allMetaData = annotationClass
0310: .getAnnotation(SearchableAllMetaData.class);
0311: if (allMetaData != null) {
0312: if (allMetaData.enable() == EnableAll.TRUE) {
0313: allMapping.setSupported(true);
0314: } else if (allMetaData.enable() == EnableAll.FALSE) {
0315: allMapping.setSupported(false);
0316: }
0317: if (allMetaData.excludeAlias() == ExcludeAlias.TRUE) {
0318: allMapping.setExcludeAlias(true);
0319: } else if (allMetaData.excludeAlias() == ExcludeAlias.FALSE) {
0320: allMapping.setExcludeAlias(false);
0321: }
0322: if (StringUtils.hasLength(allMetaData.name())) {
0323: allMapping.setProperty(allMetaData.name());
0324: }
0325: if (allMetaData.termVector() != TermVector.NA) {
0326: allMapping.setTermVector(AnnotationsBindingUtils
0327: .convert(allMetaData.termVector()));
0328: }
0329: if (allMetaData.spellCheck() == SpellCheck.EXCLUDE) {
0330: allMapping.setSpellCheck(SpellCheckType.EXCLUDE);
0331: } else if (allMetaData.spellCheck() == SpellCheck.INCLUDE) {
0332: allMapping.setSpellCheck(SpellCheckType.INCLUDE);
0333: } else if (allMetaData.spellCheck() == SpellCheck.NA) {
0334: allMapping.setSpellCheck(SpellCheckType.NA);
0335: }
0336: allMapping.setOmitNorms(allMetaData.omitNorms());
0337: }
0338: classMapping.setAllMapping(allMapping);
0339:
0340: if (searchable.spellCheck() == SpellCheck.NA) {
0341: classMapping.setSpellCheck(SpellCheckType.NA);
0342: } else if (searchable.spellCheck() == SpellCheck.EXCLUDE) {
0343: classMapping.setSpellCheck(SpellCheckType.EXCLUDE);
0344: } else if (searchable.spellCheck() == SpellCheck.INCLUDE) {
0345: classMapping.setSpellCheck(SpellCheckType.INCLUDE);
0346: }
0347:
0348: classMapping.setBoost(searchable.boost());
0349: classMapping.setRoot(searchable.root());
0350: classMapping.setPoly(searchable.poly());
0351: if (!Object.class.equals(searchable.polyClass())) {
0352: classMapping.setPolyClass(searchable.polyClass());
0353: }
0354: if (StringUtils.hasLength(searchable.analyzer())) {
0355: classMapping.setAnalyzer(searchable.analyzer());
0356: }
0357:
0358: if (searchable.supportUnmarshall() == SupportUnmarshall.TRUE) {
0359: classMapping.setSupportUnmarshall(true);
0360: } else if (searchable.supportUnmarshall() == SupportUnmarshall.FALSE) {
0361: classMapping.setSupportUnmarshall(false);
0362: }
0363:
0364: classMapping.setManagedId(AnnotationsBindingUtils
0365: .convert(searchable.managedId()));
0366:
0367: bindConverter(classMapping, searchable.converter());
0368:
0369: processAnnotatedClass(annotationClass);
0370:
0371: if (newClassMapping) {
0372: mapping.addMapping(classMapping);
0373: }
0374:
0375: classMapping = null;
0376:
0377: return true;
0378: }
0379:
0380: private String getAliasFromSearchableClass(Class clazz,
0381: Searchable searchable) {
0382: String alias = searchable.alias();
0383: if (!StringUtils.hasLength(alias)) {
0384: alias = ClassUtils.getShortName(clazz);
0385: } else {
0386: // check if it is a lookp alias
0387: Alias aliasLookup = valueLookup.lookupAlias(alias);
0388: if (aliasLookup != null) {
0389: alias = aliasLookup.getName();
0390: }
0391: }
0392: return alias;
0393: }
0394:
0395: /**
0396: * Recursivly process the class to find all it's annotations. Lower level
0397: * class/interfaces with annotations will be added first.
0398: */
0399: private void processAnnotatedClass(Class<?> clazz) {
0400: if (clazz.equals(Class.class)) {
0401: return;
0402: }
0403: Class<?> super Clazz = clazz.getSuperclass();
0404: if (super Clazz != null && !super Clazz.equals(Object.class)) {
0405: processAnnotatedClass(super Clazz);
0406: }
0407: Class<?>[] interfaces = clazz.getInterfaces();
0408: for (Class<?> anInterface : interfaces) {
0409: processAnnotatedClass(anInterface);
0410: }
0411:
0412: SearchableConstant searchableConstant = clazz
0413: .getAnnotation(SearchableConstant.class);
0414: if (searchableConstant != null) {
0415: bindConstantMetaData(searchableConstant);
0416: }
0417:
0418: SearchableConstants searchableConstants = clazz
0419: .getAnnotation(SearchableConstants.class);
0420: if (searchableConstants != null) {
0421: for (SearchableConstant metaData : searchableConstants
0422: .value()) {
0423: bindConstantMetaData(metaData);
0424: }
0425: }
0426:
0427: SearchableDynamicMetaData searchableDynamicMetaData = clazz
0428: .getAnnotation(SearchableDynamicMetaData.class);
0429: if (searchableDynamicMetaData != null) {
0430: bindDynamicMetaData(searchableDynamicMetaData);
0431: }
0432: SearchableDynamicMetaDatas searchableDynamicMetaDatas = clazz
0433: .getAnnotation(SearchableDynamicMetaDatas.class);
0434: if (searchableDynamicMetaDatas != null) {
0435: for (SearchableDynamicMetaData metaData : searchableDynamicMetaDatas
0436: .value()) {
0437: bindDynamicMetaData(metaData);
0438: }
0439: }
0440:
0441: // handles recursive extends and the original extend
0442: if (clazz.isAnnotationPresent(Searchable.class)) {
0443: Searchable searchable = clazz
0444: .getAnnotation(Searchable.class);
0445: String[] extend = searchable.extend();
0446: if (extend.length != 0) {
0447: ArrayList<String> extendedMappings = new ArrayList<String>();
0448: if (classMapping.getExtendedAliases() != null) {
0449: extendedMappings.addAll(Arrays.asList(classMapping
0450: .getExtendedAliases()));
0451: }
0452: for (String extendedAlias : extend) {
0453: Alias extendedAliasLookup = valueLookup
0454: .lookupAlias(extendedAlias);
0455: if (extendedAliasLookup == null) {
0456: extendedMappings.add(extendedAlias);
0457: } else {
0458: extendedMappings.add(extendedAliasLookup
0459: .getName());
0460: }
0461: }
0462: classMapping.setExtendedAliases(extendedMappings
0463: .toArray(new String[extendedMappings.size()]));
0464: }
0465: }
0466:
0467: // if the super class has Searchable annotation as well, add it to the list of extends
0468: Class<?> super Class = clazz.getSuperclass();
0469: if (super Class != null
0470: && super Class.isAnnotationPresent(Searchable.class)) {
0471: Searchable super Searchable = super Class
0472: .getAnnotation(Searchable.class);
0473: String alias = getAliasFromSearchableClass(super Class,
0474: super Searchable);
0475: ArrayList<String> extendedMappings = new ArrayList<String>();
0476: if (classMapping.getExtendedAliases() != null) {
0477: extendedMappings.addAll(Arrays.asList(classMapping
0478: .getExtendedAliases()));
0479: }
0480: extendedMappings.add(alias);
0481: classMapping.setExtendedAliases(extendedMappings
0482: .toArray(new String[extendedMappings.size()]));
0483: }
0484:
0485: for (Field field : clazz.getDeclaredFields()) {
0486: for (Annotation annotation : field.getAnnotations()) {
0487: processsAnnotatedElement(clazz, ClassUtils
0488: .getShortNameForField(field), "field", field
0489: .getType(), field.getGenericType(), annotation,
0490: field);
0491: }
0492: }
0493: for (Method method : clazz.getDeclaredMethods()) {
0494: if (!method.isSynthetic()
0495: && !method.isBridge()
0496: && !Modifier.isStatic(method.getModifiers())
0497: && method.getParameterTypes().length == 0
0498: && method.getReturnType() != void.class
0499: && (method.getName().startsWith("get") || method
0500: .getName().startsWith("is"))) {
0501:
0502: for (Annotation annotation : method.getAnnotations()) {
0503: processsAnnotatedElement(clazz, ClassUtils
0504: .getShortNameForMethod(method), "property",
0505: method.getReturnType(), method
0506: .getGenericReturnType(),
0507: annotation, method);
0508: }
0509: }
0510: }
0511: }
0512:
0513: private void processsAnnotatedElement(Class<?> searchableClass,
0514: String name, String accessor, Class<?> clazz, Type type,
0515: Annotation annotation, AnnotatedElement annotatedElement) {
0516:
0517: if (annotation instanceof SearchableId) {
0518: ClassIdPropertyMapping classPropertyMapping = new ClassIdPropertyMapping();
0519: SearchableId searchableId = (SearchableId) annotation;
0520: bindObjectMapping(classPropertyMapping, accessor, name,
0521: searchableId.accessor(), searchableClass);
0522: bindClassPropertyIdMapping(searchableId,
0523: classPropertyMapping, clazz, type, annotatedElement);
0524: classMapping.addMapping(classPropertyMapping);
0525: } else if (annotation instanceof SearchableIdComponent) {
0526: IdComponentMapping componentMapping = new IdComponentMapping();
0527: SearchableIdComponent searchableComponent = (SearchableIdComponent) annotation;
0528: bindObjectMapping(componentMapping, accessor, name,
0529: searchableComponent.accessor(), searchableClass);
0530: bindComponent(searchableComponent, componentMapping, clazz,
0531: type);
0532: classMapping.addMapping(componentMapping);
0533: } else if (annotation instanceof SearchableProperty) {
0534: ClassPropertyMapping classPropertyMapping = new ClassPropertyMapping();
0535: SearchableProperty searchableProperty = (SearchableProperty) annotation;
0536: bindObjectMapping(classPropertyMapping, accessor, name,
0537: searchableProperty.accessor(), searchableClass);
0538: bindClassPropertyMapping(searchableProperty,
0539: classPropertyMapping, annotatedElement, clazz, type);
0540: classMapping.addMapping(classPropertyMapping);
0541: } else if (annotation instanceof SearchableComponent) {
0542: ComponentMapping componentMapping = new ComponentMapping();
0543: SearchableComponent searchableComponent = (SearchableComponent) annotation;
0544: bindObjectMapping(componentMapping, accessor, name,
0545: searchableComponent.accessor(), searchableClass);
0546: bindComponent(searchableComponent, componentMapping, clazz,
0547: type);
0548: classMapping.addMapping(componentMapping);
0549: } else if (annotation instanceof SearchableReference) {
0550: ReferenceMapping referenceMapping = new ReferenceMapping();
0551: SearchableReference searchableReference = (SearchableReference) annotation;
0552: bindObjectMapping(referenceMapping, accessor, name,
0553: searchableReference.accessor(), searchableClass);
0554: bindReference(searchableReference, referenceMapping, clazz,
0555: type);
0556: classMapping.addMapping(referenceMapping);
0557: } else if (annotation instanceof SearchableAnalyzerProperty) {
0558: ClassPropertyAnalyzerController analyzerMapping = new ClassPropertyAnalyzerController();
0559: SearchableAnalyzerProperty searchableAnalyzerProperty = (SearchableAnalyzerProperty) annotation;
0560: bindObjectMapping(analyzerMapping, accessor, name,
0561: searchableAnalyzerProperty.accessor(),
0562: searchableClass);
0563: bindAnalyzer(searchableAnalyzerProperty, analyzerMapping,
0564: clazz, type);
0565: classMapping.addMapping(analyzerMapping);
0566: } else if (annotation instanceof SearchableBoostProperty) {
0567: ClassBoostPropertyMapping boostPropertyMapping = new ClassBoostPropertyMapping();
0568: SearchableBoostProperty searchableBoostProperty = (SearchableBoostProperty) annotation;
0569: bindObjectMapping(boostPropertyMapping, accessor, name,
0570: searchableBoostProperty.accessor(), searchableClass);
0571: bindBoost(searchableBoostProperty, boostPropertyMapping,
0572: clazz, type);
0573: classMapping.addMapping(boostPropertyMapping);
0574: } else if (annotation instanceof SearchableParent) {
0575: ParentMapping parentMapping = new ParentMapping();
0576: SearchableParent searchableParent = (SearchableParent) annotation;
0577: bindObjectMapping(parentMapping, accessor, name,
0578: searchableParent.accessor(), searchableClass);
0579: bindParent(searchableParent, parentMapping, clazz, type);
0580: classMapping.addMapping(parentMapping);
0581: } else if (annotation instanceof SearchableCascading) {
0582: PlainCascadeMapping cascadeMapping = new PlainCascadeMapping();
0583: SearchableCascading searchableCascading = (SearchableCascading) annotation;
0584: bindObjectMapping(cascadeMapping, accessor, name,
0585: searchableCascading.accessor(), searchableClass);
0586: bindCascade(searchableCascading, cascadeMapping, clazz,
0587: type);
0588: classMapping.addMapping(cascadeMapping);
0589: } else if ((annotation instanceof SearchableMetaData)
0590: || (annotation instanceof SearchableMetaDatas)) {
0591: if (!annotatedElement
0592: .isAnnotationPresent(SearchableProperty.class)
0593: && !annotatedElement
0594: .isAnnotationPresent(SearchableId.class)) {
0595: throw new MappingException(
0596: "SearchableMetaData/s annotation exists without a SearchableProperty/Id, it will be ignored");
0597: }
0598: }
0599: }
0600:
0601: private void bindCascade(SearchableCascading searchableCascading,
0602: PlainCascadeMapping cascadeMapping, Class<?> clazz,
0603: Type type) {
0604: bindConverter(cascadeMapping, searchableCascading.converter(),
0605: clazz, type);
0606: bindCascades(searchableCascading.cascade(), cascadeMapping);
0607: }
0608:
0609: private void bindParent(SearchableParent searchableParent,
0610: ParentMapping parentMapping, Class<?> clazz, Type type) {
0611: bindConverter(parentMapping, searchableParent.converter(),
0612: clazz, type);
0613: bindCascades(searchableParent.cascade(), parentMapping);
0614: }
0615:
0616: private void bindBoost(
0617: SearchableBoostProperty searchableBoostProperty,
0618: ClassBoostPropertyMapping boostPropertyMapping,
0619: Class<?> clazz, Type type) {
0620: bindConverter(boostPropertyMapping, searchableBoostProperty
0621: .converter(), clazz, type);
0622: boostPropertyMapping.setDefaultBoost(searchableBoostProperty
0623: .defaultValue());
0624: }
0625:
0626: private void bindAnalyzer(
0627: SearchableAnalyzerProperty searchableAnalyzerProperty,
0628: ClassPropertyAnalyzerController analyzerMapping,
0629: Class<?> clazz, Type type) {
0630: bindConverter(analyzerMapping, searchableAnalyzerProperty
0631: .converter(), clazz, type);
0632:
0633: if (StringUtils.hasLength(searchableAnalyzerProperty
0634: .nullAnalyzer())) {
0635: analyzerMapping.setNullAnalyzer(searchableAnalyzerProperty
0636: .nullAnalyzer());
0637: }
0638: }
0639:
0640: private void bindReference(SearchableReference searchableReference,
0641: ReferenceMapping referenceMapping, Class<?> clazz, Type type) {
0642:
0643: bindConverter(referenceMapping,
0644: searchableReference.converter(), clazz, type);
0645:
0646: if (StringUtils.hasLength(searchableReference.refAlias())) {
0647: referenceMapping
0648: .setRefAliases(getAliases(searchableReference
0649: .refAlias()));
0650: } else {
0651: referenceMapping.setRefClass(AnnotationsBindingUtils
0652: .getCollectionParameterClass(clazz, type));
0653: }
0654:
0655: if (StringUtils.hasLength(searchableReference
0656: .refComponentAlias())) {
0657: referenceMapping.setRefCompAlias(searchableReference
0658: .refComponentAlias());
0659: }
0660: bindCascades(searchableReference.cascade(), referenceMapping);
0661: }
0662:
0663: private void bindComponent(SearchableComponent searchableComponent,
0664: ComponentMapping componentMapping, Class<?> clazz, Type type) {
0665:
0666: bindConverter(componentMapping,
0667: searchableComponent.converter(), clazz, type);
0668:
0669: if (StringUtils.hasLength(searchableComponent.refAlias())) {
0670: componentMapping
0671: .setRefAliases(getAliases(searchableComponent
0672: .refAlias()));
0673: } else {
0674: componentMapping.setRefClass(AnnotationsBindingUtils
0675: .getCollectionParameterClass(clazz, type));
0676: }
0677:
0678: componentMapping.setMaxDepth(searchableComponent.maxDepth());
0679:
0680: componentMapping.setOverrideByName(searchableComponent
0681: .override());
0682:
0683: bindCascades(searchableComponent.cascade(), componentMapping);
0684: }
0685:
0686: private void bindComponent(
0687: SearchableIdComponent searchableComponent,
0688: ComponentMapping componentMapping, Class<?> clazz, Type type) {
0689:
0690: bindConverter(componentMapping,
0691: searchableComponent.converter(), clazz, type);
0692:
0693: if (StringUtils.hasLength(searchableComponent.refAlias())) {
0694: componentMapping
0695: .setRefAliases(getAliases(searchableComponent
0696: .refAlias()));
0697: } else {
0698: componentMapping.setRefClass(AnnotationsBindingUtils
0699: .getCollectionParameterClass(clazz, type));
0700: }
0701:
0702: componentMapping.setMaxDepth(searchableComponent.maxDepth());
0703:
0704: componentMapping.setOverrideByName(searchableComponent
0705: .override());
0706:
0707: bindCascades(searchableComponent.cascade(), componentMapping);
0708: }
0709:
0710: private void bindCascades(Cascade[] cascades,
0711: CascadeMapping cascadeMapping) {
0712: if (cascades == null || cascades.length == 0) {
0713: return;
0714: }
0715: CascadeMapping.Cascade[] mappingCascades = new CascadeMapping.Cascade[cascades.length];
0716: for (int i = 0; i < cascades.length; i++) {
0717: mappingCascades[i] = AnnotationsBindingUtils
0718: .convert(cascades[i]);
0719: }
0720: cascadeMapping.setCascades(mappingCascades);
0721: }
0722:
0723: /**
0724: * Need to be almost exactly as <code>bindClassPropertyMapping</code>.
0725: */
0726: private void bindClassPropertyIdMapping(
0727: SearchableId searchableProp,
0728: ClassIdPropertyMapping classPropertyMapping,
0729: Class<?> clazz, Type type, AnnotatedElement annotatedElement)
0730: throws MappingException {
0731:
0732: bindConverter(classPropertyMapping, searchableProp
0733: .idConverter());
0734:
0735: // No need for type in property id, since it will not be a collection
0736:
0737: classPropertyMapping.setBoost(searchableProp.boost());
0738: classPropertyMapping.setManagedId(AnnotationsBindingUtils
0739: .convert(searchableProp.managedId()));
0740: classPropertyMapping.setManagedIdIndex(AnnotationsBindingUtils
0741: .convert(searchableProp.managedIdIndex()));
0742: classPropertyMapping.setOverrideByName(searchableProp
0743: .override());
0744:
0745: SearchableMetaData metaData = annotatedElement
0746: .getAnnotation(SearchableMetaData.class);
0747: SearchableMetaDatas metaDatas = annotatedElement
0748: .getAnnotation(SearchableMetaDatas.class);
0749:
0750: if (StringUtils.hasLength(searchableProp.converter())) {
0751: classPropertyMapping
0752: .setManagedIdConverterName(searchableProp
0753: .converter());
0754: } else {
0755: classPropertyMapping.setManagedIdConverter(getConverter(
0756: clazz, type));
0757: }
0758:
0759: // check if we need to create a metadata because of the SearchId
0760: // here we differ from the searchProperty mapping, since it is perfectly
0761: // fine not to create one if there are no meta-data definitions (an internal
0762: // one will be created during the process phase)
0763: if (StringUtils.hasLength(searchableProp.name())) {
0764: ClassPropertyMetaDataMapping mdMapping = new ClassPropertyMetaDataMapping();
0765: String name = searchableProp.name();
0766: if (!StringUtils.hasLength(name)) {
0767: name = classPropertyMapping.getName();
0768: }
0769: mdMapping.setName(valueLookup.lookupMetaDataName(name));
0770: mdMapping.setPath(new StaticPropertyPath(mdMapping
0771: .getName()));
0772: mdMapping.setBoost(classPropertyMapping.getBoost());
0773:
0774: mdMapping.setAccessor(classPropertyMapping.getAccessor());
0775: mdMapping.setPropertyName(classPropertyMapping
0776: .getPropertyName());
0777:
0778: bindConverter(mdMapping, searchableProp.converter(), clazz,
0779: type);
0780: bindSpellCheck(mdMapping, searchableProp.spellCheck());
0781:
0782: mdMapping.setStore(AnnotationsBindingUtils
0783: .convert(searchableProp.store()));
0784: mdMapping.setIndex(AnnotationsBindingUtils
0785: .convert(searchableProp.index()));
0786: mdMapping.setTermVector(AnnotationsBindingUtils
0787: .convert(searchableProp.termVector()));
0788: mdMapping.setOmitNorms(searchableProp.omitNorms());
0789: mdMapping.setReverse(AnnotationsBindingUtils
0790: .convert(searchableProp.reverse()));
0791:
0792: handleFormat(mdMapping, name, searchableProp.format());
0793:
0794: if (StringUtils.hasLength(searchableProp.analyzer())) {
0795: mdMapping.setAnalyzer(searchableProp.analyzer());
0796: } else {
0797: mdMapping.setAnalyzer(classMapping.getAnalyzer());
0798: }
0799: mdMapping.setExcludeFromAll(AnnotationsBindingUtils
0800: .convert(searchableProp.excludeFromAll()));
0801:
0802: classPropertyMapping.addMapping(mdMapping);
0803: }
0804:
0805: if (metaData != null) {
0806: bindMetaData(metaData, classPropertyMapping, clazz, type);
0807: }
0808: if (metaDatas != null) {
0809: for (SearchableMetaData searchableMetaData : metaDatas
0810: .value()) {
0811: bindMetaData(searchableMetaData, classPropertyMapping,
0812: clazz, type);
0813: }
0814: }
0815: }
0816:
0817: /**
0818: * Need to be almost exactly as <code>bindClassPropertyIdMapping</code>.
0819: */
0820: private void bindClassPropertyMapping(
0821: SearchableProperty searchableProp,
0822: ClassPropertyMapping classPropertyMapping,
0823: AnnotatedElement annotatedElement, Class<?> clazz, Type type)
0824: throws MappingException {
0825:
0826: bindConverter(classPropertyMapping, searchableProp
0827: .propertyConverter());
0828:
0829: if (!searchableProp.type().equals(Object.class)) {
0830: classPropertyMapping.setClassName(searchableProp.type()
0831: .getName());
0832: } else {
0833: // check if it is a colleciton. If it is, try to infer the
0834: // type using generics
0835: classPropertyMapping.setClassName(AnnotationsBindingUtils
0836: .getCollectionParameterClassName(clazz, type));
0837: }
0838:
0839: if (StringUtils.hasLength(searchableProp.converter())) {
0840: classPropertyMapping
0841: .setManagedIdConverterName(searchableProp
0842: .converter());
0843: } else {
0844: classPropertyMapping.setManagedIdConverter(getConverter(
0845: clazz, type));
0846: }
0847:
0848: classPropertyMapping.setBoost(searchableProp.boost());
0849: classPropertyMapping.setManagedId(AnnotationsBindingUtils
0850: .convert(searchableProp.managedId()));
0851: classPropertyMapping.setManagedIdIndex(AnnotationsBindingUtils
0852: .convert(searchableProp.managedIdIndex()));
0853: classPropertyMapping.setOverrideByName(searchableProp
0854: .override());
0855:
0856: SearchableMetaData metaData = annotatedElement
0857: .getAnnotation(SearchableMetaData.class);
0858: SearchableMetaDatas metaDatas = annotatedElement
0859: .getAnnotation(SearchableMetaDatas.class);
0860:
0861: boolean hasMetaDataAnnotations = metaData != null
0862: || metaDatas != null;
0863:
0864: // check if we need to create a metadata because of the SearchProperty
0865: if (StringUtils.hasLength(searchableProp.name())
0866: || !hasMetaDataAnnotations) {
0867: ClassPropertyMetaDataMapping mdMapping = new ClassPropertyMetaDataMapping();
0868: String name = searchableProp.name();
0869: if (!StringUtils.hasLength(name)) {
0870: name = classPropertyMapping.getName();
0871: }
0872: mdMapping.setName(valueLookup.lookupMetaDataName(name));
0873: mdMapping.setPath(new StaticPropertyPath(mdMapping
0874: .getName()));
0875: mdMapping.setBoost(classPropertyMapping.getBoost());
0876:
0877: bindConverter(mdMapping, searchableProp.converter(), clazz,
0878: type);
0879: bindSpellCheck(mdMapping, searchableProp.spellCheck());
0880:
0881: mdMapping.setAccessor(classPropertyMapping.getAccessor());
0882: mdMapping.setPropertyName(classPropertyMapping
0883: .getPropertyName());
0884:
0885: mdMapping.setStore(AnnotationsBindingUtils
0886: .convert(searchableProp.store()));
0887: mdMapping.setIndex(AnnotationsBindingUtils
0888: .convert(searchableProp.index()));
0889: mdMapping.setTermVector(AnnotationsBindingUtils
0890: .convert(searchableProp.termVector()));
0891: mdMapping.setOmitNorms(searchableProp.omitNorms());
0892: mdMapping.setReverse(AnnotationsBindingUtils
0893: .convert(searchableProp.reverse()));
0894:
0895: handleFormat(mdMapping, name, searchableProp.format());
0896:
0897: mdMapping.setInternal(false);
0898:
0899: if (StringUtils.hasLength(searchableProp.analyzer())) {
0900: mdMapping.setAnalyzer(searchableProp.analyzer());
0901: } else {
0902: mdMapping.setAnalyzer(classMapping.getAnalyzer());
0903: }
0904: if (StringUtils.hasLength(searchableProp.nullValue())) {
0905: mdMapping.setNullValue(searchableProp.nullValue());
0906: }
0907: mdMapping.setExcludeFromAll(AnnotationsBindingUtils
0908: .convert(searchableProp.excludeFromAll()));
0909:
0910: classPropertyMapping.addMapping(mdMapping);
0911: }
0912:
0913: if (metaData != null) {
0914: bindMetaData(metaData, classPropertyMapping, clazz, type);
0915: }
0916: if (metaDatas != null) {
0917: for (SearchableMetaData searchableMetaData : metaDatas
0918: .value()) {
0919: bindMetaData(searchableMetaData, classPropertyMapping,
0920: clazz, type);
0921: }
0922: }
0923: }
0924:
0925: private void bindMetaData(SearchableMetaData searchableMetaData,
0926: ClassPropertyMapping classPropertyMapping, Class<?> clazz,
0927: Type type) {
0928:
0929: ClassPropertyMetaDataMapping mdMapping = new ClassPropertyMetaDataMapping();
0930: String name = searchableMetaData.name();
0931: mdMapping.setName(valueLookup.lookupMetaDataName(name));
0932: mdMapping.setPath(new StaticPropertyPath(mdMapping.getName()));
0933: if (searchableMetaData.boost() == 1.0f) {
0934: mdMapping.setBoost(classPropertyMapping.getBoost());
0935: } else {
0936: mdMapping.setBoost(searchableMetaData.boost());
0937: }
0938:
0939: bindConverter(mdMapping, searchableMetaData.converter(), clazz,
0940: type);
0941: bindSpellCheck(mdMapping, searchableMetaData.spellCheck());
0942:
0943: mdMapping.setAccessor(classPropertyMapping.getAccessor());
0944: mdMapping.setPropertyName(classPropertyMapping
0945: .getPropertyName());
0946:
0947: mdMapping.setStore(AnnotationsBindingUtils
0948: .convert(searchableMetaData.store()));
0949: mdMapping.setIndex(AnnotationsBindingUtils
0950: .convert(searchableMetaData.index()));
0951: mdMapping.setTermVector(AnnotationsBindingUtils
0952: .convert(searchableMetaData.termVector()));
0953: mdMapping.setOmitNorms(searchableMetaData.omitNorms());
0954: mdMapping.setReverse(AnnotationsBindingUtils
0955: .convert(searchableMetaData.reverse()));
0956:
0957: handleFormat(mdMapping, name, searchableMetaData.format());
0958:
0959: mdMapping.setInternal(false);
0960:
0961: if (StringUtils.hasLength(searchableMetaData.analyzer())) {
0962: mdMapping.setAnalyzer(searchableMetaData.analyzer());
0963: } else {
0964: mdMapping.setAnalyzer(classMapping.getAnalyzer());
0965: }
0966: if (StringUtils.hasLength(searchableMetaData.nullValue())) {
0967: mdMapping.setNullValue(searchableMetaData.nullValue());
0968: }
0969: mdMapping.setExcludeFromAll(AnnotationsBindingUtils
0970: .convert(searchableMetaData.excludeFromAll()));
0971:
0972: classPropertyMapping.addMapping(mdMapping);
0973: }
0974:
0975: private void bindDynamicMetaData(
0976: SearchableDynamicMetaData searchableMetaData) {
0977:
0978: DynamicMetaDataMapping mdMapping = new DynamicMetaDataMapping();
0979: String name = searchableMetaData.name();
0980: mdMapping.setName(valueLookup.lookupMetaDataName(name));
0981: mdMapping.setPath(new StaticPropertyPath(mdMapping.getName()));
0982: mdMapping.setBoost(searchableMetaData.boost());
0983:
0984: mdMapping.setOverrideByName(searchableMetaData.override());
0985:
0986: mdMapping.setConverterName(searchableMetaData.converter());
0987: mdMapping.setExpression(searchableMetaData.expression());
0988: if (StringUtils.hasLength(searchableMetaData.format())) {
0989: mdMapping.setFormat(searchableMetaData.format());
0990: }
0991: mdMapping.setType(searchableMetaData.type());
0992:
0993: mdMapping.setStore(AnnotationsBindingUtils
0994: .convert(searchableMetaData.store()));
0995: mdMapping.setIndex(AnnotationsBindingUtils
0996: .convert(searchableMetaData.index()));
0997: mdMapping.setTermVector(AnnotationsBindingUtils
0998: .convert(searchableMetaData.termVector()));
0999: mdMapping.setReverse(AnnotationsBindingUtils
1000: .convert(searchableMetaData.reverse()));
1001:
1002: mdMapping.setInternal(false);
1003:
1004: bindSpellCheck(mdMapping, searchableMetaData.spellCheck());
1005:
1006: if (StringUtils.hasLength(searchableMetaData.analyzer())) {
1007: mdMapping.setAnalyzer(searchableMetaData.analyzer());
1008: } else {
1009: mdMapping.setAnalyzer(classMapping.getAnalyzer());
1010: }
1011: if (StringUtils.hasLength(searchableMetaData.nullValue())) {
1012: mdMapping.setNullValue(searchableMetaData.nullValue());
1013: }
1014: mdMapping.setExcludeFromAll(AnnotationsBindingUtils
1015: .convert(searchableMetaData.excludeFromAll()));
1016:
1017: classMapping.addMapping(mdMapping);
1018: }
1019:
1020: private void bindConstantMetaData(
1021: SearchableConstant searchableConstant) {
1022: ConstantMetaDataMapping constantMapping = new ConstantMetaDataMapping();
1023: constantMapping.setName(valueLookup
1024: .lookupMetaDataName(searchableConstant.name()));
1025: constantMapping.setBoost(searchableConstant.boost());
1026: constantMapping.setStore(AnnotationsBindingUtils
1027: .convert(searchableConstant.store()));
1028: constantMapping.setIndex(AnnotationsBindingUtils
1029: .convert(searchableConstant.index()));
1030: constantMapping.setTermVector(AnnotationsBindingUtils
1031: .convert(searchableConstant.termVector()));
1032: constantMapping.setOmitNorms(searchableConstant.omitNorms());
1033: if (StringUtils.hasLength(searchableConstant.analyzer())) {
1034: constantMapping.setAnalyzer(searchableConstant.analyzer());
1035: } else {
1036: constantMapping.setAnalyzer(classMapping.getAnalyzer());
1037: }
1038: constantMapping.setExcludeFromAll(AnnotationsBindingUtils
1039: .convert(searchableConstant.excludeFromAll()));
1040: constantMapping
1041: .setOverrideByName(searchableConstant.override());
1042: for (String value : searchableConstant.values()) {
1043: constantMapping.addMetaDataValue(valueLookup
1044: .lookupMetaDataValue(value));
1045: }
1046: bindSpellCheck(constantMapping, searchableConstant.spellCheck());
1047: classMapping.addMapping(constantMapping);
1048: }
1049:
1050: private void bindConverter(Mapping mapping, String converterName) {
1051: bindConverter(mapping, converterName, null, null);
1052: }
1053:
1054: private void bindSpellCheck(
1055: InternalResourcePropertyMapping mapping,
1056: SpellCheck spellCheck) {
1057: if (spellCheck == SpellCheck.EXCLUDE) {
1058: mapping.setSpellCheck(SpellCheckType.EXCLUDE);
1059: } else if (spellCheck == SpellCheck.INCLUDE) {
1060: mapping.setSpellCheck(SpellCheckType.INCLUDE);
1061: } else if (spellCheck == SpellCheck.NA) {
1062: mapping.setSpellCheck(SpellCheckType.NA);
1063: }
1064: }
1065:
1066: private void bindConverter(Mapping mapping, String converterName,
1067: Class<?> clazz, Type type) {
1068: if (StringUtils.hasLength(converterName)) {
1069: mapping.setConverterName(converterName);
1070: return;
1071: }
1072: if (clazz == null) {
1073: return;
1074: }
1075: mapping.setConverter(getConverter(clazz, type));
1076: }
1077:
1078: public Converter getConverter(Class<?> clazz, Type type) {
1079: Class<?> actualClass = AnnotationsBindingUtils
1080: .getCollectionParameterClass(clazz, type);
1081: if (actualClass == null) {
1082: actualClass = clazz;
1083: }
1084: SearchableClassConverter searchableClassConverter = actualClass
1085: .getAnnotation(SearchableClassConverter.class);
1086: if (searchableClassConverter == null) {
1087: return null;
1088: }
1089: Object objConverter;
1090: try {
1091: objConverter = searchableClassConverter.value()
1092: .newInstance();
1093: } catch (Exception e) {
1094: throw new MappingException("Failed to create converter ["
1095: + searchableClassConverter.value().getName() + "]",
1096: e);
1097: }
1098: if (!(objConverter instanceof Converter)) {
1099: throw new MappingException("[" + searchableClassConverter
1100: + "] does not implement Converter interface");
1101: }
1102: Converter converter = (Converter) objConverter;
1103: if (searchableClassConverter.settings().length > 0
1104: && !(converter instanceof CompassConfigurable)) {
1105: throw new MappingException(
1106: "["
1107: + searchableClassConverter
1108: + "] does not implement CompassConfigurable"
1109: + " interface, but has settings set, please implement it so settings can be injected");
1110: }
1111: if (converter instanceof CompassConfigurable) {
1112: CompassSettings settings = new CompassSettings();
1113: for (int i = 0; i < searchableClassConverter.settings().length; i++) {
1114: SearchSetting setting = searchableClassConverter
1115: .settings()[i];
1116: settings.setSetting(setting.name(), setting.value());
1117: }
1118: ((CompassConfigurable) converter).configure(settings);
1119: }
1120: return converter;
1121: }
1122:
1123: private void bindObjectMapping(ObjectMapping objectMapping,
1124: String actualAccessor, String name,
1125: String annotationAccessor, Class<?> searchableClass) {
1126: if (!StringUtils.hasLength(annotationAccessor)) {
1127: objectMapping.setAccessor(actualAccessor);
1128: } else {
1129: objectMapping.setAccessor(annotationAccessor);
1130: }
1131: objectMapping.setName(name);
1132: objectMapping.setPropertyName(name);
1133: // set the defined in alias for multiple ref aliases
1134: // note, with annotation, we might not have @Searchable defined on
1135: // the class, so we are using the FQN class name instead
1136: if (searchableClass.isAnnotationPresent(Searchable.class)) {
1137: Searchable searchable = searchableClass
1138: .getAnnotation(Searchable.class);
1139: if (StringUtils.hasLength(searchable.alias())) {
1140: objectMapping.setDefinedInAlias(searchable.alias());
1141: } else {
1142: objectMapping.setDefinedInAlias(searchableClass
1143: .getName());
1144: }
1145: } else {
1146: objectMapping.setDefinedInAlias(searchableClass.getName());
1147: }
1148: }
1149:
1150: /**
1151: * Returns a string array of aliases from a comma separated string
1152: */
1153: private String[] getAliases(String commaSeparatedAliases) {
1154: ArrayList<String> aliases = new ArrayList<String>();
1155: StringTokenizer st = new StringTokenizer(commaSeparatedAliases,
1156: ",");
1157: while (st.hasMoreTokens()) {
1158: String extendedAlias = st.nextToken().trim();
1159: Alias alias = valueLookup.lookupAlias(extendedAlias);
1160: if (alias == null) {
1161: aliases.add(extendedAlias);
1162: } else {
1163: aliases.add(alias.getName());
1164: }
1165: }
1166: return aliases.toArray(new String[aliases.size()]);
1167: }
1168:
1169: private void handleFormat(ClassPropertyMetaDataMapping mdMapping,
1170: String name, String format) {
1171: if (!StringUtils.hasLength(format)) {
1172: return;
1173: }
1174: if (mdMapping.getConverter() == null) {
1175: if (format == null) {
1176: format = valueLookup.lookupMetaDataFormat(name);
1177: }
1178: if (format != null) {
1179: mdMapping
1180: .setConverter(new MetaDataFormatDelegateConverter(
1181: format));
1182: }
1183: }
1184: }
1185: }
|