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