/*
* Copyright 2004-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.compass.core.mapping.support;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.compass.core.engine.naming.PropertyPath;
import org.compass.core.engine.subindex.SubIndexHash;
import org.compass.core.mapping.AliasMapping;
import org.compass.core.mapping.AllMapping;
import org.compass.core.mapping.BoostPropertyMapping;
import org.compass.core.mapping.Cascade;
import org.compass.core.mapping.CascadeMapping;
import org.compass.core.mapping.Mapping;
import org.compass.core.mapping.MappingException;
import org.compass.core.mapping.ResourceAnalyzerController;
import org.compass.core.mapping.ResourceIdMappingProvider;
import org.compass.core.mapping.ResourcePropertyMapping;
import org.compass.core.mapping.SpellCheck;
import org.compass.core.mapping.internal.DefaultAllMapping;
import org.compass.core.mapping.internal.InternalResourceMapping;
import org.compass.core.mapping.internal.PostProcessingMapping;
/**
* @author kimchy
*/
public abstract class AbstractResourceMapping extends AbstractMultipleMapping implements InternalResourceMapping,
AliasMapping, PostProcessingMapping {
private String alias;
private SubIndexHash subIndexHash;
private String[] extendedAliases = new String[0];
private String[] extendingAliases = new String[0];
private String analyzer;
private float boost = 1.0f;
private boolean isRoot = true;
private AllMapping allMapping = new DefaultAllMapping();
private SpellCheck spellCheck = SpellCheck.NA;
private String uidProperty;
private Mapping[] idMappings;
private ResourcePropertyMapping[] idPropertyMappings;
private CascadeMapping[] cascades;
private Map<String, ResourcePropertyMapping[]> resourcePropertyMappingsByNameMap;
private Map<PropertyPath, ResourcePropertyMapping> resourcePropertyMappingsByPathMap;
private String[] resourcePropertyNames;
private boolean hasSpecificAnalyzerPerResourceProperty;
private ResourceAnalyzerController analyzerController;
private BoostPropertyMapping boostPropertyMapping;
/**
* Gets the idMappings of the resource.
*/
public Mapping[] getIdMappings() {
if (idMappings == null) {
buildResourceIds();
}
return idMappings;
}
public AllMapping getAllMapping() {
return allMapping;
}
public void setAllMapping(AllMapping allMapping) {
this.allMapping = allMapping;
}
public SpellCheck getSpellCheck() {
return spellCheck;
}
public void setSpellCheck(SpellCheck spellCheck) {
this.spellCheck = spellCheck;
}
public ResourcePropertyMapping[] getResourceIdMappings() {
if (idPropertyMappings == null) {
buildResourceIds();
}
return idPropertyMappings;
}
protected void copy(AbstractResourceMapping resourceMapping) {
super.copy(resourceMapping);
shallowCopy(resourceMapping);
}
public void shallowCopy(AbstractResourceMapping resourceMapping) {
super.shallowCopy(resourceMapping);
resourceMapping.setAlias(getAlias());
resourceMapping.setSubIndexHash(getSubIndexHash());
resourceMapping.setExtendedAliases(getExtendedAliases());
resourceMapping.setExtendingAliases(getExtendingAliases());
resourceMapping.setRoot(isRoot());
resourceMapping.setBoost(getBoost());
resourceMapping.setAnalyzer(getAnalyzer());
resourceMapping.setUIDPath(getUIDPath());
resourceMapping.setAllMapping(getAllMapping().copy());
resourceMapping.setSpellCheck(getSpellCheck());
if (boostPropertyMapping != null) {
resourceMapping.boostPropertyMapping = (BoostPropertyMapping) boostPropertyMapping.copy();
}
if (analyzerController != null) {
resourceMapping.analyzerController = (ResourceAnalyzerController) analyzerController.copy();
}
}
public void postProcess() throws MappingException {
doPostProcess();
buildResourcePropertyMap();
buildAnalyzerSpecificFlag();
buildResourceIds();
}
protected abstract void doPostProcess() throws MappingException;
private void buildResourceIds() {
ArrayList<Mapping> resourceIds = new ArrayList<Mapping>();
ArrayList<ResourcePropertyMapping> resourceIdPropertyMappings = new ArrayList<ResourcePropertyMapping>();
for (Iterator it = mappingsIt(); it.hasNext();) {
Mapping mapping = (Mapping) it.next();
if (mapping instanceof ResourceIdMappingProvider) {
Mapping[] tempIds = ((ResourceIdMappingProvider) mapping).getIdMappings();
for (Mapping tempId : tempIds) {
if (tempId != null) {
resourceIds.add(tempId);
}
}
ResourcePropertyMapping[] tempPropertyIds = ((ResourceIdMappingProvider) mapping).getResourceIdMappings();
for (ResourcePropertyMapping tempPropertyId : tempPropertyIds) {
if (tempPropertyId != null) {
resourceIdPropertyMappings.add(tempPropertyId);
}
}
}
}
idMappings = resourceIds.toArray(new Mapping[resourceIds.size()]);
idPropertyMappings = resourceIdPropertyMappings.toArray(new ResourcePropertyMapping[resourceIdPropertyMappings.size()]);
}
private void buildResourcePropertyMap() {
resourcePropertyMappingsByPathMap = new HashMap<PropertyPath, ResourcePropertyMapping>();
HashMap<String, ArrayList<ResourcePropertyMapping>> tempMap = new HashMap<String, ArrayList<ResourcePropertyMapping>>();
ResourcePropertyMapping[] resourcePropertyMappings = getResourcePropertyMappings();
for (ResourcePropertyMapping resourcePropertyMapping : resourcePropertyMappings) {
resourcePropertyMappingsByPathMap.put(resourcePropertyMapping.getPath(), resourcePropertyMapping);
ArrayList<ResourcePropertyMapping> propertyList = tempMap.get(resourcePropertyMapping.getName());
if (propertyList == null) {
propertyList = new ArrayList<ResourcePropertyMapping>();
tempMap.put(resourcePropertyMapping.getName(), propertyList);
}
propertyList.add(resourcePropertyMapping);
}
resourcePropertyNames = new String[tempMap.size()];
int i = 0;
resourcePropertyMappingsByNameMap = new HashMap<String, ResourcePropertyMapping[]>();
for (Map.Entry<String, ArrayList<ResourcePropertyMapping>> entry : tempMap.entrySet()) {
String propertyName = entry.getKey();
resourcePropertyNames[i++] = propertyName;
ArrayList<ResourcePropertyMapping> propertyList = entry.getValue();
resourcePropertyMappingsByNameMap.put(propertyName,
propertyList.toArray(new ResourcePropertyMapping[propertyList.size()]));
}
}
private void buildAnalyzerSpecificFlag() {
for (String propertyName : resourcePropertyMappingsByNameMap.keySet()) {
ResourcePropertyMapping[] mappings = resourcePropertyMappingsByNameMap.get(propertyName);
// the system will validate in the mappings if there are different
// analyzers (or null) set to the same property mapping, here we can
// just use the first one
if (mappings[0].getAnalyzer() != null) {
// no need to say we have a specific analyzer if it is the same as the one set on the resource
if (analyzer == null || !analyzer.equals(mappings[0].getAnalyzer())) {
hasSpecificAnalyzerPerResourceProperty = true;
}
}
}
}
/**
* No duplicate names are allowed when added an id (applies the property
* names)
*/
public int addMapping(Mapping mapping) {
if (mapping instanceof ResourceAnalyzerController) {
analyzerController = (ResourceAnalyzerController) mapping;
}
if (mapping instanceof BoostPropertyMapping) {
boostPropertyMapping = (BoostPropertyMapping) mapping;
}
return super.addMapping(mapping);
}
public ResourcePropertyMapping[] getResourcePropertyMappings(String propertyName) {
return resourcePropertyMappingsByNameMap.get(propertyName);
}
public ResourcePropertyMapping getResourcePropertyMapping(String propertyName) {
ResourcePropertyMapping[] retVal = getResourcePropertyMappings(propertyName);
if (retVal == null) {
return null;
}
return retVal[0];
}
public ResourcePropertyMapping getResourcePropertyMappingByPath(PropertyPath path) {
return resourcePropertyMappingsByPathMap.get(path);
}
public CascadeMapping[] getCascadeMappings() {
return cascades;
}
public boolean operationAllowed(Cascade cascade) {
if (isRoot()) {
return true;
}
if (cascades == null || cascades.length == 0) {
return false;
}
for (CascadeMapping cascade1 : cascades) {
if (cascade1.shouldCascade(cascade)) {
return true;
}
}
return false;
}
public String getAlias() {
return alias;
}
public void setAlias(String alias) {
this.alias = alias;
}
public String[] getExtendedAliases() {
return extendedAliases;
}
public void setExtendedAliases(String[] extendedMappings) {
this.extendedAliases = extendedMappings;
}
public void setUIDPath(String uid) {
this.uidProperty = uid;
}
public String getUIDPath() {
return this.uidProperty;
}
public float getBoost() {
return boost;
}
public void setBoost(float boost) {
this.boost = boost;
}
public String getAnalyzer() {
return analyzer;
}
public void setAnalyzer(String analyzer) {
this.analyzer = analyzer;
}
public boolean isRoot() {
return isRoot;
}
public void setRoot(boolean isRoot) {
this.isRoot = isRoot;
}
public SubIndexHash getSubIndexHash() {
return subIndexHash;
}
public void setSubIndexHash(SubIndexHash subIndexHash) {
this.subIndexHash = subIndexHash;
}
public boolean hasSpecificAnalyzerPerResourceProperty() {
return hasSpecificAnalyzerPerResourceProperty;
}
public ResourceAnalyzerController getAnalyzerController() {
return analyzerController;
}
public void setAnalyzerController(ResourceAnalyzerController analyzerController) {
this.analyzerController = analyzerController;
}
public BoostPropertyMapping getBoostPropertyMapping() {
return boostPropertyMapping;
}
public void setBoostPropertyMapping(BoostPropertyMapping boostPropertyMapping) {
this.boostPropertyMapping = boostPropertyMapping;
}
public String[] getResourcePropertyNames() {
return resourcePropertyNames;
}
public String[] getExtendingAliases() {
return extendingAliases;
}
public void setExtendingAliases(String[] extendingAliases) {
this.extendingAliases = extendingAliases;
}
public void setCascades(CascadeMapping[] cascades) {
this.cascades = cascades;
}
}