Skip to content

Commit

Permalink
manage xdoc anchor name conflicts (2 classes with same anchor)
Browse files Browse the repository at this point in the history
  • Loading branch information
hboutemy committed Feb 10, 2022
1 parent 676c4ab commit 2590c0f
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 22 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ target/
bin
.idea/
*.iml
.factorypath
pom.xml.releaseBackup
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.Stack;
Expand All @@ -42,6 +44,7 @@
import org.codehaus.modello.model.ModelField;
import org.codehaus.modello.model.Version;
import org.codehaus.modello.model.VersionRange;
import org.codehaus.modello.plugin.xdoc.metadata.XdocClassMetadata;
import org.codehaus.modello.plugin.xdoc.metadata.XdocFieldMetadata;
import org.codehaus.modello.plugin.xsd.XsdModelHelper;
import org.codehaus.modello.plugins.xml.AbstractXmlGenerator;
Expand Down Expand Up @@ -171,11 +174,16 @@ private void generateXdoc( Properties parameters )
* Get the anchor name by which model classes can be accessed in the generated xdoc/html file.
*
* @param tagName the name of the XML tag of the model class
* @param modelClass the model class, that eventually can have customized anchor name
* @return the corresponding anchor name
*/
private String getAnchorName( String tagName )
private String getAnchorName( String tagName, ModelClass modelClass )
{
return "class_" + tagName ;
XdocClassMetadata xdocClassMetadata = (XdocClassMetadata) modelClass.getMetadata( XdocClassMetadata.ID );

String anchorName = xdocClassMetadata.getAnchorName();

return "class_" + ( anchorName == null ? tagName : anchorName );
}

/**
Expand All @@ -186,7 +194,7 @@ private String getAnchorName( String tagName )
*/
private void writeModelDescriptor( XMLWriter w, ModelClass rootModelClass )
{
writeElementDescriptor( w, rootModelClass, null, new HashSet<String>() );
writeElementDescriptor( w, rootModelClass, null, new HashSet<>(), new HashMap<>() );
}

/**
Expand All @@ -195,26 +203,37 @@ private void writeModelDescriptor( XMLWriter w, ModelClass rootModelClass )
* @param w the output writer
* @param modelClass the mode class to describe
* @param association the association we are coming from (can be <code>null</code>)
* @param written set of data already written
* @param writtenIds set of data already written ids
* @param writtenAnchors map of already written anchors with corresponding ids
*/
private void writeElementDescriptor( XMLWriter w, ModelClass modelClass, ModelAssociation association,
Set<String> written )
Set<String> writtenIds, Map<String, String> writtenAnchors )
{
String tagName = resolveTagName( modelClass, association );

String id = getId( tagName, modelClass );
if ( written.contains( id ) )
if ( writtenIds.contains( id ) )
{
// tag already written for this model class accessed as this tag name
return;
}
written.add( id );
writtenIds.add( id );

written.add( tagName );
String anchorName = getAnchorName( tagName, modelClass );
if ( writtenAnchors.containsKey( anchorName ) )
{
// TODO use logging API?
System.out.println( "[warn] model class " + id + " with tagName " + tagName + " gets duplicate anchorName "
+ anchorName + ", conflicting with model class " + writtenAnchors.get( anchorName ) );
}
else
{
writtenAnchors.put( anchorName, id );
}

w.startElement( "a" );

w.addAttribute( "name", getAnchorName( tagName ) );
w.addAttribute( "name", anchorName );

w.endElement();

Expand Down Expand Up @@ -257,9 +276,9 @@ private void writeElementDescriptor( XMLWriter w, ModelClass modelClass, ModelAs
ModelAssociation assoc = (ModelAssociation) f;
ModelClass fieldModelClass = getModel().getClass( assoc.getTo(), getGeneratedVersion() );

if ( !written.contains( getId( resolveTagName( fieldModelClass, assoc ), fieldModelClass ) ) )
if ( !writtenIds.contains( getId( resolveTagName( fieldModelClass, assoc ), fieldModelClass ) ) )
{
writeElementDescriptor( w, fieldModelClass, assoc, written );
writeElementDescriptor( w, fieldModelClass, assoc, writtenIds, writtenAnchors );
}
}
}
Expand Down Expand Up @@ -350,7 +369,7 @@ private void writeFieldsTable( XMLWriter w, List<ModelField> fields, boolean ele
if ( isInnerAssociation( f ) )
{
w.startElement( "a" );
w.addAttribute( "href", "#" + getAnchorName( itemTagName ) );
w.addAttribute( "href", "#" + getAnchorName( itemTagName, assoc.getToClass() ) );
w.writeText( itemTagName );
w.endElement();
}
Expand Down Expand Up @@ -497,7 +516,7 @@ private String getElementXmlDescriptor( ModelClass modelClass, ModelAssociation
String tagName = resolveTagName( modelClass, association );

// <tagName
sb.append( "&lt;<a href=\"#" ).append( getAnchorName( tagName ) ).append( "\">" );
sb.append( "&lt;<a href=\"#" ).append( getAnchorName( tagName, modelClass ) ).append( "\">" );
sb.append( tagName ).append( "</a>" );

boolean addNewline = false;
Expand Down Expand Up @@ -672,7 +691,7 @@ else if ( ModelDefault.PROPERTIES.equals( f.getType() ) )
* @param modelClass the class we are looking for the tag name
* @param association the association where this class is used
* @return the tag name to use
* @todo refactor to use resolveTagName helpers instead
* @todo refactor to use XmlModelHelpers.resolveTagName helpers instead
*/
private String resolveTagName( ModelClass modelClass, ModelAssociation association )
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,16 @@ public class XdocClassMetadata
implements ClassMetadata
{
public static final String ID = XdocClassMetadata.class.getName();

private String anchorName;

public String getAnchorName()
{
return anchorName;
}

public void setAnchorName( String anchorName )
{
this.anchorName = anchorName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,15 @@ public class XdocMetadataPlugin
implements MetadataPlugin
{
public static final String XDOC_SEPARATOR = "xdoc.separator";
public static final String XDOC_ANCHORNAME = "xdoc.anchorName";

public ClassMetadata getClassMetadata( ModelClass clazz, Map<String, String> data )
{
return new XdocClassMetadata();
XdocClassMetadata metadata = new XdocClassMetadata();

metadata.setAnchorName( getString( data, XDOC_ANCHORNAME ) );

return metadata;
}

public InterfaceMetadata getInterfaceMetadata( ModelInterface iface, Map<String, String> data )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@ public void testXdocGenerator()
checkFeaturesXdocGenerator();
checkSettingsXdocGenerator();
}

public void testHtmlToXml() throws Exception

public void testHtmlToXml()
throws Exception
{
ModelloCore modello = (ModelloCore) lookup( ModelloCore.ROLE );

Expand All @@ -79,11 +80,11 @@ public void testHtmlToXml() throws Exception
Properties parameters = getModelloParameters( "1.0.0" );

modello.generate( model, "xdoc", parameters );

Diff diff = DiffBuilder.compare( Input.fromStream( XdocGeneratorTest.class.getResourceAsStream( "/html4.expected.xml" ) ) )
.withTest( Input.fromFile( new File( getOutputDirectory(), "html4.xml" ) ) ).build();
assertFalse(diff.toString(), diff.hasDifferences());

assertFalse( diff.toString(), diff.hasDifferences() );
}

private void checkMavenXdocGenerator()
Expand Down Expand Up @@ -166,7 +167,7 @@ public void checkSettingsXdocGenerator()

String content = FileUtils.fileRead( new File( getOutputDirectory(), "settings.xml" ), "UTF-8" );

assertTrue( "Properties field was erroneously documented", !content.contains("&lt;properties/&gt;"));
assertTrue( "Properties field was erroneously documented", !content.contains("&lt;properties/&gt;") );
}

/**
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -616,7 +616,7 @@
<models>
<model>src/main/mdo/modello.mdo</model>
</models>
<version>1.8.0</version>
<version>2.0.0</version>
</configuration>
<executions>
<execution>
Expand Down
9 changes: 9 additions & 0 deletions src/main/mdo/modello.mdo
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,15 @@
</description>
<comment>see org.codehaus.modello.plugin.model.ModelMetadataPlugin</comment>
</field>
<field xml.attribute="true" xml.tagName="xdoc.anchorName">
<name>anchorName</name>
<version>2.0.0+</version>
<type>String</type>
<description>
Define a anchor base name to be used in XML content, which can be different from the XML tag name name.
</description>
<comment>see org.codehaus.modello.plugin.model.ModelMetadataPlugin</comment>
</field>
<field xml.attribute="true" xml.tagName="java.enabled">
<name>enabled</name>
<version>1.0.0+</version>
Expand Down

0 comments on commit 2590c0f

Please sign in to comment.