View Javadoc
1   /*
2    * Copyright 2006 Werner Guttmann
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5    * in compliance with the License. You may obtain a copy of the License at
6    *
7    * http://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software distributed under the License
10   * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11   * or implied. See the License for the specific language governing permissions and limitations under
12   * the License.
13   */
14  package org.exolab.castor.builder.conflictresolution;
15  
16  import java.util.Enumeration;
17  
18  import org.apache.commons.logging.Log;
19  import org.apache.commons.logging.LogFactory;
20  import org.exolab.castor.builder.SGStateInfo;
21  import org.exolab.castor.builder.binding.XPathHelper;
22  import org.exolab.castor.builder.info.ClassInfo;
23  import org.exolab.castor.builder.info.nature.XMLInfoNature;
24  import org.exolab.castor.util.dialog.ConsoleDialog;
25  import org.exolab.castor.xml.schema.Annotated;
26  import org.exolab.castor.xml.schema.ElementDecl;
27  import org.exolab.castor.xml.schema.SchemaNames;
28  import org.exolab.javasource.JClass;
29  
30  /**
31   * An implementation of {@link ClassNameCRStrategy} that reports any conflict notifications to a log
32   * file, basically stating what classes have been overwriten as a result of such a name conflict.
33   *
34   * @author <a href="mailto:werner DOT guttmann AT gmx DOT net">Werner Guttmann</a>
35   * @since 1.1
36   */
37  public final class InformViaLogClassNameCRStrategy extends BaseClassNameCRStrategy
38      implements ClassNameCRStrategy {
39  
40    /** Logger instance used for logging naming conflicts. */
41    private static final Log LOG = LogFactory.getLog(InformViaLogClassNameCRStrategy.class);
42    /** Name of this strategy. */
43    public static final String NAME = "informViaLog";
44  
45    /**
46     * Creates an instance of this name conflict resolution strategy, that will emit warnings to the
47     * user as part of a standard logging aproach.
48     */
49    public InformViaLogClassNameCRStrategy() {
50      // Nothing to do.
51    }
52  
53    /**
54     * Handle a class name conflict between newClassInfo and conflict.
55     *
56     * @param state SourceGeneration state
57     * @param newClassInfo ClassInfo for the new class
58     * @param conflict JClass for the existing class
59     * @return the provided source generator state, as modified by the strategy
60     * @see org.exolab.castor.builder.conflictresolution.ClassNameCRStrategy
61     *      #dealWithClassNameConflict(org.exolab.castor.builder.SGStateInfo,
62     *      org.exolab.castor.builder.info.ClassInfo, org.exolab.javasource.JClass)
63     */
64    public SGStateInfo dealWithClassNameConflict(final SGStateInfo state,
65        final ClassInfo newClassInfo, final JClass conflict) {
66      // If the ClassInfo are equal, we can just return
67      ClassInfo oldClassInfo = state.resolve(conflict);
68      if (oldClassInfo == newClassInfo) {
69        return state;
70      }
71  
72      // Find the Schema structures that are conflicting
73      Annotated a1 = null;
74      Annotated a2 = null;
75  
76      // Loop until we exhaust the Enumeration or until we have found both
77      Enumeration enumeration = state.keys();
78      while (enumeration.hasMoreElements() && (a1 == null || a2 == null)) {
79        Object key = enumeration.nextElement();
80        if (!(key instanceof Annotated)) {
81          continue;
82        }
83  
84        ClassInfo cInfo = state.resolve(key);
85        if (newClassInfo == cInfo) {
86          a1 = (Annotated) key;
87        } else if (oldClassInfo == cInfo) {
88          a2 = (Annotated) key;
89        }
90      }
91  
92      String annotated1XPath;
93      String annotated2XPath;
94  
95      StringBuilder message = new StringBuilder();
96      message.append("Warning: A class name generation conflict has occured between ");
97  
98      if (a1 != null) {
99        message.append(SchemaNames.getStructureName(a1));
100       message.append(" '");
101       if (a1 instanceof ElementDecl) {
102         ElementDecl element = (ElementDecl) a1;
103         annotated1XPath = XPathHelper.getSchemaLocation(a1) + "[/complexType:"
104             + element.getType().getName() + "]";
105         message.append(annotated1XPath);
106       } else {
107         message.append(XPathHelper.getSchemaLocation(a1));
108       }
109     } else {
110       if (newClassInfo.hasNature(XMLInfoNature.class.getName())) {
111         XMLInfoNature xmlNature = new XMLInfoNature(newClassInfo);
112         message.append(xmlNature.getNodeTypeName());
113         message.append(" '");
114         message.append(xmlNature.getNodeName());
115       }
116     }
117     message.append("' and ");
118     if (a2 != null) {
119       message.append(SchemaNames.getStructureName(a2));
120       message.append(" '");
121       if (a2 instanceof ElementDecl) {
122         ElementDecl element = (ElementDecl) a2;
123         annotated2XPath = XPathHelper.getSchemaLocation(a2) + "[/complexType:"
124             + element.getType().getName() + "]";
125         message.append(annotated2XPath);
126       } else {
127         message.append(XPathHelper.getSchemaLocation(a2));
128       }
129     } else {
130       if (oldClassInfo.hasNature(XMLInfoNature.class.getName())) {
131         XMLInfoNature xmlNature = new XMLInfoNature(oldClassInfo);
132         message.append(xmlNature.getNodeTypeName());
133         message.append(" '");
134         message.append(xmlNature.getNodeName());
135       }
136     }
137     message.append("'. Please use a Binding file to solve this problem.");
138     LOG.warn(message);
139     return state;
140   }
141 
142   /**
143    * Returns the name of the strategy.
144    * 
145    * @return the name of the strategy.
146    * @see org.exolab.castor.builder.conflictresolution.ClassNameCRStrategy#getName()
147    */
148   public String getName() {
149     return NAME;
150   }
151 
152   /**
153    * Sets the console dialog to use with this strategy.
154    *
155    * @param dialog the console dialog to use with this strategy.
156    * @see org.exolab.castor.builder.conflictresolution.ClassNameCRStrategy#
157    *      setConsoleDialog(org.exolab.castor.util.dialog.ConsoleDialog)
158    */
159   public void setConsoleDialog(final ConsoleDialog dialog) {
160     // No console dialog needed.
161   }
162 
163   /**
164    * Presents the user with a console dialog, asking for confirmation whether an existing file
165    * should be overwritten (or not).
166    *
167    * @param filename the filename to potentially overwrite.
168    * @return whether or not the file should be overwritten.
169    *
170    * @see org.exolab.castor.builder.conflictresolution.ClassNameCRStrategy
171    *      #dealWithFileOverwrite(java.lang.String, boolean)
172    */
173   public boolean dealWithFileOverwrite(final String filename) {
174     LOG.warn(filename + " already exists, but will be overwritten.");
175     return true;
176   }
177 
178 }