/* * Copyright 2006 Werner Guttmann * * 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.exolab.castor.builder.conflictresolution; import java.util.Enumeration; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.exolab.castor.builder.SGStateInfo; import org.exolab.castor.builder.binding.XPathHelper; import org.exolab.castor.builder.info.ClassInfo; import org.exolab.castor.builder.info.nature.XMLInfoNature; import org.exolab.castor.util.dialog.ConsoleDialog; import org.exolab.castor.xml.schema.Annotated; import org.exolab.castor.xml.schema.ElementDecl; import org.exolab.castor.xml.schema.SchemaNames; import org.exolab.javasource.JClass; /** * An implementation of {@link ClassNameCRStrategy} that * reports any conflict notifications to a log file, basically * stating what classes have been overwriten as a result of such * a name conflict. * * @author <a href="mailto:werner DOT guttmann AT gmx DOT net">Werner Guttmann</a> * @since 1.1 */ public final class InformViaLogClassNameCRStrategy extends BaseClassNameCRStrategy implements ClassNameCRStrategy { /** Logger instance used for logging naming conflicts. */ private static final Log LOG = LogFactory.getLog(InformViaLogClassNameCRStrategy.class); /** Name of this strategy. */ public static final String NAME = "informViaLog"; /** * Creates an instance of this name conflict resolution strategy, that will * emit warnings to the user as part of a standard logging aproach. */ public InformViaLogClassNameCRStrategy() { // Nothing to do. } /** * Handle a class name conflict between newClassInfo and conflict. * * @param state SourceGeneration state * @param newClassInfo ClassInfo for the new class * @param conflict JClass for the existing class * @return the provided source generator state, as modified by the strategy * @see org.exolab.castor.builder.conflictresolution.ClassNameCRStrategy * #dealWithClassNameConflict(org.exolab.castor.builder.SGStateInfo, * org.exolab.castor.builder.info.ClassInfo, * org.exolab.javasource.JClass) */ public SGStateInfo dealWithClassNameConflict(final SGStateInfo state, final ClassInfo newClassInfo, final JClass conflict) { // If the ClassInfo are equal, we can just return ClassInfo oldClassInfo = state.resolve(conflict); if (oldClassInfo == newClassInfo) { return state; } // Find the Schema structures that are conflicting Annotated a1 = null; Annotated a2 = null; // Loop until we exhaust the Enumeration or until we have found both Enumeration enumeration = state.keys(); while (enumeration.hasMoreElements() && (a1 == null || a2 == null)) { Object key = enumeration.nextElement(); if (!(key instanceof Annotated)) { continue; } ClassInfo cInfo = state.resolve(key); if (newClassInfo == cInfo) { a1 = (Annotated) key; } else if (oldClassInfo == cInfo) { a2 = (Annotated) key; } } String annotated1XPath; String annotated2XPath; StringBuilder message = new StringBuilder(); message.append("Warning: A class name generation conflict has occured between "); if (a1 != null) { message.append(SchemaNames.getStructureName(a1)); message.append(" '"); if (a1 instanceof ElementDecl) { ElementDecl element = (ElementDecl) a1; annotated1XPath = XPathHelper.getSchemaLocation(a1) + "[/complexType:" + element.getType().getName() + "]"; message.append(annotated1XPath); } else { message.append(XPathHelper.getSchemaLocation(a1)); } } else { if (newClassInfo.hasNature(XMLInfoNature.class.getName())) { XMLInfoNature xmlNature = new XMLInfoNature(newClassInfo); message.append(xmlNature.getNodeTypeName()); message.append(" '"); message.append(xmlNature.getNodeName()); } } message.append("' and "); if (a2 != null) { message.append(SchemaNames.getStructureName(a2)); message.append(" '"); if (a2 instanceof ElementDecl) { ElementDecl element = (ElementDecl) a2; annotated2XPath = XPathHelper.getSchemaLocation(a2) + "[/complexType:" + element.getType().getName() + "]"; message.append(annotated2XPath); } else { message.append(XPathHelper.getSchemaLocation(a2)); } } else { if (oldClassInfo.hasNature(XMLInfoNature.class.getName())) { XMLInfoNature xmlNature = new XMLInfoNature(oldClassInfo); message.append(xmlNature.getNodeTypeName()); message.append(" '"); message.append(xmlNature.getNodeName()); } } message.append("'. Please use a Binding file to solve this problem."); LOG.warn(message); return state; } /** * Returns the name of the strategy. * @return the name of the strategy. * @see org.exolab.castor.builder.conflictresolution.ClassNameCRStrategy#getName() */ public String getName() { return NAME; } /** * Sets the console dialog to use with this strategy. * * @param dialog the console dialog to use with this strategy. * @see org.exolab.castor.builder.conflictresolution.ClassNameCRStrategy# * setConsoleDialog(org.exolab.castor.util.dialog.ConsoleDialog) */ public void setConsoleDialog(final ConsoleDialog dialog) { // No console dialog needed. } /** * Presents the user with a console dialog, asking for confirmation whether * an existing file should be overwritten (or not). * * @param filename the filename to potentially overwrite. * @return whether or not the file should be overwritten. * * @see org.exolab.castor.builder.conflictresolution.ClassNameCRStrategy * #dealWithFileOverwrite(java.lang.String, boolean) */ public boolean dealWithFileOverwrite(final String filename) { LOG.warn(filename + " already exists, but will be overwritten."); return true; } }