/*
* 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;
}
}