25
25
import java .io .File ;
26
26
import java .io .IOException ;
27
27
import java .io .Writer ;
28
+ import java .util .HashMap ;
28
29
import java .util .HashSet ;
29
30
import java .util .List ;
31
+ import java .util .Map ;
30
32
import java .util .Properties ;
31
33
import java .util .Set ;
32
34
import java .util .Stack ;
42
44
import org .codehaus .modello .model .ModelField ;
43
45
import org .codehaus .modello .model .Version ;
44
46
import org .codehaus .modello .model .VersionRange ;
47
+ import org .codehaus .modello .plugin .xdoc .metadata .XdocClassMetadata ;
45
48
import org .codehaus .modello .plugin .xdoc .metadata .XdocFieldMetadata ;
46
49
import org .codehaus .modello .plugin .xsd .XsdModelHelper ;
47
50
import org .codehaus .modello .plugins .xml .AbstractXmlGenerator ;
@@ -171,11 +174,16 @@ private void generateXdoc( Properties parameters )
171
174
* Get the anchor name by which model classes can be accessed in the generated xdoc/html file.
172
175
*
173
176
* @param tagName the name of the XML tag of the model class
177
+ * @param modelClass the model class, that eventually can have customized anchor name
174
178
* @return the corresponding anchor name
175
179
*/
176
- private String getAnchorName ( String tagName )
180
+ private String getAnchorName ( String tagName , ModelClass modelClass )
177
181
{
178
- return "class_" + tagName ;
182
+ XdocClassMetadata xdocClassMetadata = (XdocClassMetadata ) modelClass .getMetadata ( XdocClassMetadata .ID );
183
+
184
+ String anchorName = xdocClassMetadata .getAnchorName ();
185
+
186
+ return "class_" + ( anchorName == null ? tagName : anchorName );
179
187
}
180
188
181
189
/**
@@ -186,7 +194,7 @@ private String getAnchorName( String tagName )
186
194
*/
187
195
private void writeModelDescriptor ( XMLWriter w , ModelClass rootModelClass )
188
196
{
189
- writeElementDescriptor ( w , rootModelClass , null , new HashSet <String >() );
197
+ writeElementDescriptor ( w , rootModelClass , null , new HashSet <>(), new HashMap < >() );
190
198
}
191
199
192
200
/**
@@ -195,26 +203,37 @@ private void writeModelDescriptor( XMLWriter w, ModelClass rootModelClass )
195
203
* @param w the output writer
196
204
* @param modelClass the mode class to describe
197
205
* @param association the association we are coming from (can be <code>null</code>)
198
- * @param written set of data already written
206
+ * @param writtenIds set of data already written ids
207
+ * @param writtenAnchors map of already written anchors with corresponding ids
199
208
*/
200
209
private void writeElementDescriptor ( XMLWriter w , ModelClass modelClass , ModelAssociation association ,
201
- Set <String > written )
210
+ Set <String > writtenIds , Map < String , String > writtenAnchors )
202
211
{
203
212
String tagName = resolveTagName ( modelClass , association );
204
213
205
214
String id = getId ( tagName , modelClass );
206
- if ( written .contains ( id ) )
215
+ if ( writtenIds .contains ( id ) )
207
216
{
208
217
// tag already written for this model class accessed as this tag name
209
218
return ;
210
219
}
211
- written .add ( id );
220
+ writtenIds .add ( id );
212
221
213
- written .add ( tagName );
222
+ String anchorName = getAnchorName ( tagName , modelClass );
223
+ if ( writtenAnchors .containsKey ( anchorName ) )
224
+ {
225
+ // TODO use logging API?
226
+ System .out .println ( "[warn] model class " + id + " with tagName " + tagName + " gets duplicate anchorName "
227
+ + anchorName + ", conflicting with model class " + writtenAnchors .get ( anchorName ) );
228
+ }
229
+ else
230
+ {
231
+ writtenAnchors .put ( anchorName , id );
232
+ }
214
233
215
234
w .startElement ( "a" );
216
235
217
- w .addAttribute ( "name" , getAnchorName ( tagName ) );
236
+ w .addAttribute ( "name" , anchorName );
218
237
219
238
w .endElement ();
220
239
@@ -257,9 +276,9 @@ private void writeElementDescriptor( XMLWriter w, ModelClass modelClass, ModelAs
257
276
ModelAssociation assoc = (ModelAssociation ) f ;
258
277
ModelClass fieldModelClass = getModel ().getClass ( assoc .getTo (), getGeneratedVersion () );
259
278
260
- if ( !written .contains ( getId ( resolveTagName ( fieldModelClass , assoc ), fieldModelClass ) ) )
279
+ if ( !writtenIds .contains ( getId ( resolveTagName ( fieldModelClass , assoc ), fieldModelClass ) ) )
261
280
{
262
- writeElementDescriptor ( w , fieldModelClass , assoc , written );
281
+ writeElementDescriptor ( w , fieldModelClass , assoc , writtenIds , writtenAnchors );
263
282
}
264
283
}
265
284
}
@@ -350,7 +369,7 @@ private void writeFieldsTable( XMLWriter w, List<ModelField> fields, boolean ele
350
369
if ( isInnerAssociation ( f ) )
351
370
{
352
371
w .startElement ( "a" );
353
- w .addAttribute ( "href" , "#" + getAnchorName ( itemTagName ) );
372
+ w .addAttribute ( "href" , "#" + getAnchorName ( itemTagName , assoc . getToClass () ) );
354
373
w .writeText ( itemTagName );
355
374
w .endElement ();
356
375
}
@@ -497,7 +516,7 @@ private String getElementXmlDescriptor( ModelClass modelClass, ModelAssociation
497
516
String tagName = resolveTagName ( modelClass , association );
498
517
499
518
// <tagName
500
- sb .append ( "<<a href=\" #" ).append ( getAnchorName ( tagName ) ).append ( "\" >" );
519
+ sb .append ( "<<a href=\" #" ).append ( getAnchorName ( tagName , modelClass ) ).append ( "\" >" );
501
520
sb .append ( tagName ).append ( "</a>" );
502
521
503
522
boolean addNewline = false ;
@@ -672,7 +691,7 @@ else if ( ModelDefault.PROPERTIES.equals( f.getType() ) )
672
691
* @param modelClass the class we are looking for the tag name
673
692
* @param association the association where this class is used
674
693
* @return the tag name to use
675
- * @todo refactor to use resolveTagName helpers instead
694
+ * @todo refactor to use XmlModelHelpers. resolveTagName helpers instead
676
695
*/
677
696
private String resolveTagName ( ModelClass modelClass , ModelAssociation association )
678
697
{
0 commit comments