/*
* 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.config.process;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import org.compass.core.config.CompassSettings;
import org.compass.core.converter.ConverterLookup;
import org.compass.core.engine.naming.PropertyNamingStrategy;
import org.compass.core.mapping.AliasMapping;
import org.compass.core.mapping.CompassMapping;
import org.compass.core.mapping.Mapping;
import org.compass.core.mapping.MappingException;
import org.compass.core.mapping.internal.InternalAliasMapping;
import org.compass.core.mapping.internal.InternalCompassMapping;
/**
* Goes over all the {@link org.compass.core.mapping.AliasMapping}s in Compass and resolves
* which one the mapping extends ({@link org.compass.core.mapping.AliasMapping#getExtendedAliases()}
* and which one are extending this alias ({@link org.compass.core.mapping.AliasMapping#getExtendingAliases()}.
*
* @author kimchy
*/
public class ResolveExtendsMappingProcessor implements MappingProcessor {
public CompassMapping process(CompassMapping compassMapping, PropertyNamingStrategy namingStrategy,
ConverterLookup converterLookup, CompassSettings settings) throws MappingException {
ArrayList<AliasMapping> innerMappingsCopy = new ArrayList<AliasMapping>();
for (AliasMapping origAliasMapping : compassMapping.getMappings()) {
InternalAliasMapping aliasMapping = (InternalAliasMapping) origAliasMapping.shallowCopy();
resolveExtends(compassMapping, aliasMapping, origAliasMapping);
innerMappingsCopy.add(aliasMapping);
}
((InternalCompassMapping) compassMapping).clearMappings();
for (AliasMapping anInnerMappingsCopy : innerMappingsCopy) {
((InternalCompassMapping) compassMapping).addMapping(anInnerMappingsCopy);
}
for (AliasMapping aliasMapping : compassMapping.getMappings()) {
resolveExtending(compassMapping, aliasMapping, new HashSet<String>());
}
return compassMapping;
}
/**
* Resolves (recursivly) and sets the extending mapping section of {@link org.compass.core.mapping.AliasMapping}.
*/
private void resolveExtending(CompassMapping compassMapping, AliasMapping aliasMapping, HashSet<String> extendingAliases) {
if (aliasMapping.getExtendedAliases() != null) {
for (int i = 0; i < aliasMapping.getExtendedAliases().length; i++) {
String extendedAlias = aliasMapping.getExtendedAliases()[i];
InternalAliasMapping extendedAliasMapping = (InternalAliasMapping) compassMapping.getAliasMapping(extendedAlias);
if (extendedAliasMapping.getExtendingAliases() != null) {
for (int j = 0; j < extendedAliasMapping.getExtendingAliases().length; j++) {
extendingAliases.add(extendedAliasMapping.getExtendingAliases()[j]);
}
}
extendingAliases.add(aliasMapping.getAlias());
extendedAliasMapping.setExtendingAliases(extendingAliases.toArray(new String[extendingAliases.size()]));
resolveExtending(compassMapping, extendedAliasMapping, extendingAliases);
}
}
}
/**
* Resolves (recursivly) all the extended aliases and addes their mappings (copy) into the alias mapping.
*/
private void resolveExtends(CompassMapping compassMapping, InternalAliasMapping aliasMapping, AliasMapping copyFromAliasMapping)
throws MappingException {
if (copyFromAliasMapping.getExtendedAliases() != null) {
for (int i = 0; i < copyFromAliasMapping.getExtendedAliases().length; i++) {
String extendedAlias = copyFromAliasMapping.getExtendedAliases()[i];
AliasMapping extendedAliasMapping = compassMapping.getAliasMapping(extendedAlias);
if (extendedAliasMapping == null) {
throw new MappingException("Failed to find alias [" + extendedAlias + "] in alias ["
+ aliasMapping.getAlias() + "] extends section");
}
// recursivly call in order to resolve extends. Note, we copy the extended alias mapping
// since we do not share mappings
resolveExtends(compassMapping, aliasMapping, (AliasMapping) extendedAliasMapping.copy());
}
}
for (Iterator aliasMappingIt = copyFromAliasMapping.mappingsIt(); aliasMappingIt.hasNext();) {
aliasMapping.addMapping((Mapping) aliasMappingIt.next());
}
}
}