This one is from the Naked Objects .ORG team, who provide (though don't necessarily recommend) support for declaring field order at the class level. Example implementation below. Some points to note:
- It's in Swing so you can just cut and paste and run it
- It defines a custom annotation (UiFieldOrder) and custom Inspector (FieldOrderInspector) to detect it
- The Inspector overrides inspectEntity (ie. class-level) rather than inspectTrait (ie. field-level)
- It defines a FieldOrderInspectionResultProcessor that sorts the properties/actions
package com.myapp;
import static org.metawidget.inspector.InspectionResultConstants.*;
import java.lang.annotation.*;
import java.util.*;
import javax.swing.*;
import org.metawidget.inspectionresultprocessor.iface.*;
import org.metawidget.inspector.annotation.*;
import org.metawidget.inspector.composite.*;
import org.metawidget.inspector.impl.*;
import org.metawidget.inspector.propertytype.*;
import org.metawidget.swing.*;
import org.metawidget.util.*;
import org.w3c.dom.*;
public class Main {
public static void main( String[] args ) {
Person person = new Person();
SwingMetawidget metawidget = new SwingMetawidget();
metawidget.setInspector( new CompositeInspector( new CompositeInspectorConfig().setInspectors(
new PropertyTypeInspector(),
new MetawidgetAnnotationInspector(),
new FieldOrderInspector() ) ) );
metawidget.addInspectionResultProcessor( new FieldOrderInspectionResultProcessor() );
metawidget.setToInspect( person );
JFrame frame = new JFrame( "Metawidget Tutorial" );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.getContentPane().add( metawidget );
frame.setSize( 400, 250 );
frame.setVisible( true );
}
@UiFieldOrder( { "name", "age", "retired", "notes" } )
static class Person {
public String name;
public int age;
public boolean retired;
@UiLarge
public String notes;
}
@Retention( RetentionPolicy.RUNTIME )
@Target( { ElementType.TYPE } )
static @interface UiFieldOrder {
String[] value();
}
static class FieldOrderInspector
extends BaseObjectInspector {
@Override
protected Map<String, String> inspectEntity( Class<?> declaredClass, Class<?> actualClass )
throws Exception {
Map<String, String> attributes = CollectionUtils.newHashMap();
UiFieldOrder fieldOrder = actualClass.getAnnotation( UiFieldOrder.class );
if ( fieldOrder != null ) {
attributes.put( "field-order", ArrayUtils.toString( fieldOrder.value() ) );
}
return attributes;
}
}
static class FieldOrderInspectionResultProcessor
implements InspectionResultProcessor<SwingMetawidget> {
public String processInspectionResult( String inspectionResult, SwingMetawidget metawidget, Object toInspect, String type, String... names ) {
try {
// Start a new document
//
// (Android 1.1 did not cope well with shuffling the nodes of an existing document)
Document newDocument = XmlUtils.newDocument();
Element newInspectionResultRoot = newDocument.createElementNS( NAMESPACE, ROOT );
Document document = XmlUtils.documentFromString( inspectionResult );
Element inspectionResultRoot = document.getDocumentElement();
XmlUtils.setMapAsAttributes( newInspectionResultRoot, XmlUtils.getAttributesAsMap( inspectionResultRoot ) );
newDocument.appendChild( newInspectionResultRoot );
Element entity = (Element) inspectionResultRoot.getChildNodes().item( 0 );
Element newEntity = newDocument.createElementNS( NAMESPACE, ENTITY );
XmlUtils.setMapAsAttributes( newEntity, XmlUtils.getAttributesAsMap( entity ) );
newInspectionResultRoot.appendChild( newEntity );
// Look up the field-order (if any)
String fieldOrder = entity.getAttribute( "field-order" );
if ( fieldOrder == null ) {
return inspectionResult;
}
String[] fieldOrderArray = ArrayUtils.fromString( fieldOrder );
for ( String field : fieldOrderArray ) {
Element trait = XmlUtils.getChildWithAttributeValue( entity, NAME, field );
newEntity.appendChild( XmlUtils.importElement( newDocument, trait ) );
}
// Return the new document
return XmlUtils.documentToString( newInspectionResultRoot.getOwnerDocument(), false );
} catch ( Exception e ) {
throw InspectionResultProcessorException.newException( e );
}
}
}
}
import static org.metawidget.inspector.InspectionResultConstants.*;
import java.lang.annotation.*;
import java.util.*;
import javax.swing.*;
import org.metawidget.inspectionresultprocessor.iface.*;
import org.metawidget.inspector.annotation.*;
import org.metawidget.inspector.composite.*;
import org.metawidget.inspector.impl.*;
import org.metawidget.inspector.propertytype.*;
import org.metawidget.swing.*;
import org.metawidget.util.*;
import org.w3c.dom.*;
public class Main {
public static void main( String[] args ) {
Person person = new Person();
SwingMetawidget metawidget = new SwingMetawidget();
metawidget.setInspector( new CompositeInspector( new CompositeInspectorConfig().setInspectors(
new PropertyTypeInspector(),
new MetawidgetAnnotationInspector(),
new FieldOrderInspector() ) ) );
metawidget.addInspectionResultProcessor( new FieldOrderInspectionResultProcessor() );
metawidget.setToInspect( person );
JFrame frame = new JFrame( "Metawidget Tutorial" );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.getContentPane().add( metawidget );
frame.setSize( 400, 250 );
frame.setVisible( true );
}
@UiFieldOrder( { "name", "age", "retired", "notes" } )
static class Person {
public String name;
public int age;
public boolean retired;
@UiLarge
public String notes;
}
@Retention( RetentionPolicy.RUNTIME )
@Target( { ElementType.TYPE } )
static @interface UiFieldOrder {
String[] value();
}
static class FieldOrderInspector
extends BaseObjectInspector {
@Override
protected Map<String, String> inspectEntity( Class<?> declaredClass, Class<?> actualClass )
throws Exception {
Map<String, String> attributes = CollectionUtils.newHashMap();
UiFieldOrder fieldOrder = actualClass.getAnnotation( UiFieldOrder.class );
if ( fieldOrder != null ) {
attributes.put( "field-order", ArrayUtils.toString( fieldOrder.value() ) );
}
return attributes;
}
}
static class FieldOrderInspectionResultProcessor
implements InspectionResultProcessor<SwingMetawidget> {
public String processInspectionResult( String inspectionResult, SwingMetawidget metawidget, Object toInspect, String type, String... names ) {
try {
// Start a new document
//
// (Android 1.1 did not cope well with shuffling the nodes of an existing document)
Document newDocument = XmlUtils.newDocument();
Element newInspectionResultRoot = newDocument.createElementNS( NAMESPACE, ROOT );
Document document = XmlUtils.documentFromString( inspectionResult );
Element inspectionResultRoot = document.getDocumentElement();
XmlUtils.setMapAsAttributes( newInspectionResultRoot, XmlUtils.getAttributesAsMap( inspectionResultRoot ) );
newDocument.appendChild( newInspectionResultRoot );
Element entity = (Element) inspectionResultRoot.getChildNodes().item( 0 );
Element newEntity = newDocument.createElementNS( NAMESPACE, ENTITY );
XmlUtils.setMapAsAttributes( newEntity, XmlUtils.getAttributesAsMap( entity ) );
newInspectionResultRoot.appendChild( newEntity );
// Look up the field-order (if any)
String fieldOrder = entity.getAttribute( "field-order" );
if ( fieldOrder == null ) {
return inspectionResult;
}
String[] fieldOrderArray = ArrayUtils.fromString( fieldOrder );
for ( String field : fieldOrderArray ) {
Element trait = XmlUtils.getChildWithAttributeValue( entity, NAME, field );
newEntity.appendChild( XmlUtils.importElement( newDocument, trait ) );
}
// Return the new document
return XmlUtils.documentToString( newInspectionResultRoot.getOwnerDocument(), false );
} catch ( Exception e ) {
throw InspectionResultProcessorException.newException( e );
}
}
}
}
0 comments:
Post a Comment