Skip to content

Commit 6584074

Browse files
dmealingclaude
andcommitted
Complete JSON-first SimpleLoader implementation with comprehensive test migration
- Add JSON schema and metadata infrastructure for SimpleLoader * Create simple-model.schema.json with complete validation schema * Add simple.types.json resource configuration * Implement JSON equivalents for all XML metadata test files - Fix SimpleLoader JSON parsing and structure issues * Correct JSON metadata structure with proper type/subType fields * Ensure all metadata objects follow JSON schema specification * Resolve MetaModelPojo null value parsing errors - Migrate test suite from XML to JSON for SimpleLoader tests * Update 15+ test files to use JSON instead of XML for SimpleLoader * Preserve XML usage for SimpleLoaderXML and XSD-specific tests * Fix XSDWriterTest to properly use SimpleLoaderXML for XML functionality * Update Maven plugin test configuration for JSON metadata - Create comprehensive JSON metadata test files * fruitbasket-metadata.json - Basic map-based metadata structure * fruitbasket-proxy-metadata.json - Proxy objects with keys and relationships * test-interface-metadata.json - Interface hierarchies with complex packages * mojo-test-metadata.json - Maven plugin integration testing This completes the JSON-first approach for SimpleLoader while maintaining backward compatibility with XML through SimpleLoaderXML. All 144 tests now pass successfully. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 91a5700 commit 6584074

23 files changed

Lines changed: 1018 additions & 25 deletions

File tree

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{"$schema": "simple-model.schema.json",
2+
"type": "metadata", "package": "simple::fruitbasket",
3+
"children": [
4+
5+
{"type": "field", "package": "simple::common", "name": "id", "subType": "long", "_isAbstract": "true",
6+
"children": [
7+
{"type": "attr", "subType": "boolean", "name": "isKey", "value": "true"}
8+
]},
9+
10+
{"type": "field", "package": "simple::common", "name": "name", "subType": "string", "_isAbstract": "true",
11+
"children": [
12+
{"type": "validator", "subType": "required"},
13+
{"type": "validator", "subType": "length",
14+
"children": [
15+
{"type": "attr", "subType": "int", "name": "min", "value": "1"},
16+
{"type": "attr", "subType": "int", "name": "max", "value": "50"}
17+
]}
18+
]},
19+
20+
{"type": "object", "name": "Basket", "subType": "map",
21+
"children": [
22+
{"type": "attr", "subType": "string", "name": "object", "value": "com.draagon.meta.loader.simple.fruitbasket.Basket"},
23+
{"type": "field", "name": "id", "super": "..::common::id"},
24+
{"type": "field", "name": "name", "super": "..::common::name"},
25+
{"type": "field", "name": "numApples", "subType": "int",
26+
"children": [
27+
{"type": "validator", "subType": "length", "min": "0", "max": "10"}
28+
]},
29+
{"type": "field", "name": "numOranges", "subType": "int",
30+
"children": [
31+
{"type": "validator", "subType": "length", "min": "0", "max": "10"}
32+
]},
33+
{"type": "field", "name": "apples", "subType": "objectArray", "objectRef": "::Apple"},
34+
{"type": "field", "name": "oranges", "subType": "objectArray", "objectRef": "::Orange"}
35+
]},
36+
37+
{"type": "object", "name": "Fruit", "subType": "map", "_isAbstract": "true",
38+
"children": [
39+
{"type": "attr", "subType": "string", "name": "object", "value": "com.draagon.meta.loader.simple.fruitbasket.Fruit"},
40+
{"type": "field", "name": "id", "super": "..::common::id"},
41+
{"type": "field", "name": "name", "super": "..::common::name"},
42+
{"type": "field", "name": "length", "subType": "int"},
43+
{"type": "field", "name": "weight", "subType": "int"},
44+
{"type": "field", "name": "inBasket", "subType": "boolean"}
45+
]},
46+
47+
{"type": "object", "name": "Apple", "super": "Fruit",
48+
"children": [
49+
{"type": "attr", "subType": "string", "name": "object", "value": "com.draagon.meta.loader.simple.fruitbasket.Apple"},
50+
{"type": "field", "name": "orchard", "subType": "string"},
51+
{"type": "field", "name": "worms", "subType": "short"}
52+
]},
53+
54+
{"type": "object", "name": "Macintosh", "super": "Apple",
55+
"children": [
56+
{"type": "attr", "subType": "string", "name": "object", "value": "com.draagon.meta.loader.simple.fruitbasket.Macintosh"}
57+
]},
58+
59+
{"type": "object", "name": "Orange", "super": "Fruit",
60+
"children": [
61+
{"type": "attr", "subType": "string", "name": "object", "value": "com.draagon.meta.loader.simple.fruitbasket.Orange"},
62+
{"type": "field", "name": "pickedDate", "subType": "date"}
63+
]}
64+
]
65+
}

maven-plugin/src/test/resources/mojo/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
<sources>
2727
<!--source>types:com/draagon/meta/loader/xml/metaobjects.types.xml</source-->
2828
<!--source>model:resource:mojo/mojo-test-metadata.xml</source -->
29-
<source>mojo/mojo-test-metadata.xml</source>
29+
<source>mojo/mojo-test-metadata.json</source>
3030
</sources>
3131
</loader>
3232
<globals>

metadata/src/main/java/com/draagon/meta/loader/simple/SimpleModelParser.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.draagon.meta.loader.simple;
22

33
import com.draagon.meta.MetaDataException;
4-
import com.draagon.meta.io.object.xml.XMLObjectReader;
4+
import com.draagon.meta.io.object.json.JsonObjectReader;
55
import com.draagon.meta.loader.model.MetaModel;
66
import com.draagon.meta.loader.model.MetaModelLoader;
77
import com.draagon.meta.loader.model.MetaModelParser;
@@ -10,6 +10,7 @@
1010

1111
import java.io.IOException;
1212
import java.io.InputStream;
13+
import java.io.InputStreamReader;
1314
import java.net.URI;
1415

1516
public class SimpleModelParser extends MetaModelParser<TypesConfig,SimpleLoader,URI> {
@@ -45,10 +46,10 @@ public void loadAndMergeFromStream( SimpleLoader intoLoader, InputStream in ) {
4546
IOException ioEx = null;
4647

4748
MetaModel metadata = null;
48-
XMLObjectReader reader = null;
49+
JsonObjectReader reader = null;
4950

5051
try {
51-
reader = new XMLObjectReader( getLoader(), in );
52+
reader = new JsonObjectReader( getLoader(), new InputStreamReader( in ));
5253
metadata = (MetaModel) reader.read( getLoader().getMetaObjectByName(MetaModel.OBJECT_NAME));
5354
} catch (IOException e) {
5455
ioEx = e;
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
package com.draagon.meta.loader.simple.xml;
2+
3+
import com.draagon.meta.MetaDataException;
4+
import com.draagon.meta.loader.LoaderOptions;
5+
import com.draagon.meta.loader.MetaDataLoader;
6+
import com.draagon.meta.loader.types.TypesConfigLoader;
7+
import com.draagon.meta.loader.model.MetaModelLoader;
8+
import com.draagon.meta.loader.mojo.MojoSupport;
9+
import com.draagon.meta.loader.simple.SimpleModelParser;
10+
import com.draagon.meta.loader.simple.SimpleTypesParser;
11+
import com.draagon.meta.loader.uri.URIHelper;
12+
13+
import java.io.*;
14+
import java.net.URI;
15+
import java.util.ArrayList;
16+
import java.util.Arrays;
17+
import java.util.List;
18+
import java.util.Map;
19+
20+
public class SimpleLoaderXML extends MetaDataLoader {
21+
22+
public final static String SIMPLE_TYPES_XML = "com/draagon/meta/loader/simple/simple.types.xml";
23+
public final static String SUBTYPE_SIMPLE = "simple";
24+
25+
private static List<URI> sourceURIs = null;
26+
27+
public SimpleLoaderXML(String name) {
28+
super(LoaderOptions.create( false, false, true), SUBTYPE_SIMPLE, name );
29+
}
30+
31+
public static SimpleLoaderXML createManual( String name, String resource ) {
32+
return createManualURIs( name, Arrays.asList(URIHelper.toURI( "model:resource:"+resource)));
33+
}
34+
35+
public static SimpleLoaderXML createManual( String name, List<String> resources ) {
36+
List<URI> uris = new ArrayList<>();
37+
for (String s : resources) uris.add(URIHelper.toURI("model:resource:"+s));
38+
return createManualURIs( name, uris);
39+
}
40+
41+
public static SimpleLoaderXML createManualURIs( String name, List<URI> uris ) {
42+
43+
SimpleLoaderXML simpleLoader = new SimpleLoaderXML( name );
44+
simpleLoader.setSourceURIs(uris);
45+
simpleLoader.init();
46+
return simpleLoader;
47+
}
48+
49+
////////////////////////////////////////////////////////////////////////////////////////////
50+
// Set ClassLoader and Sources
51+
52+
@Override
53+
protected ClassLoader getDefaultMetaDataClassLoader() {
54+
return super.getDefaultMetaDataClassLoader();
55+
}
56+
57+
@Override
58+
public SimpleLoaderXML setMetaDataClassLoader( ClassLoader classLoader ) {
59+
return super.setMetaDataClassLoader( classLoader );
60+
}
61+
62+
public SimpleLoaderXML setSourceURIs( List<URI> sourceData ) {
63+
this.sourceURIs = sourceData;
64+
return this;
65+
}
66+
67+
public List<URI> getSourceURIs() {
68+
return this.sourceURIs;
69+
}
70+
71+
////////////////////////////////////////////////////////////////////////////////////////////
72+
// MOJO Support Methods
73+
74+
@Override
75+
protected void mojoProcessSources( String sourceDir, List<String> sourceList ) {
76+
77+
String name = this.getClass().getSimpleName();
78+
if ( sourceList == null ) throw new IllegalArgumentException(
79+
"sourceList was null on setURIList for " + name);
80+
81+
List<URI> sourceURIs = new ArrayList<>();
82+
for( String s : sourceList) {
83+
if (s.indexOf(':') < 0) {
84+
if (sourceDir != null) {
85+
s = "model:file:" + s + ";" + URIHelper.URI_ARG_SOURCEDIR + "=" + sourceDir;
86+
}
87+
else if (new File(s).exists()) {
88+
s = "model:file:" + s;
89+
}
90+
else {
91+
s = "model:resource:" + s;
92+
}
93+
}
94+
sourceURIs.add(URIHelper.toURI(s));
95+
}
96+
97+
setSourceURIs(sourceURIs);
98+
}
99+
100+
@Override
101+
public void mojoInit( Map<String, String> args ) {
102+
if ( args != null ) mojoInitArgs( args );
103+
init();
104+
}
105+
106+
////////////////////////////////////////////////////////////////////////////////////////////
107+
// Initialization Methods
108+
109+
public SimpleLoaderXML init() {
110+
111+
if ( sourceURIs == null ) throw new MetaDataException( "No sourceData was specified" );
112+
113+
super.init();
114+
115+
// Load TypesConfig
116+
//SimpleTypesParser simpleTypesParser = new SimpleTypesParser( typesLoader, SIMPLE_TYPES_XML );
117+
//simpleTypesParser.loadAndMerge( this, URIHelper.toURI("types:resource:"+SIMPLE_TYPES_XML));
118+
119+
boolean typesLoaded = false;
120+
121+
// Load MetaData
122+
MetaModelLoader modelLoader = MetaModelLoader.create(
123+
getMetaDataClassLoader(),
124+
"simple",
125+
getTypesLoader() );
126+
for( URI sourceURI : sourceURIs) {
127+
128+
if (URIHelper.isTypesURI(sourceURI)) {
129+
SimpleTypesParserXML simpleTypesParser = new SimpleTypesParserXML(
130+
getTypesLoader(),
131+
getMetaDataClassLoader(),
132+
sourceURI.toString() );
133+
simpleTypesParser.loadAndMerge( this, sourceURI);
134+
typesLoaded = true;
135+
}
136+
else {
137+
if ( !typesLoaded ) {
138+
loadDefaultSimpleTypes();
139+
typesLoaded = true;
140+
}
141+
142+
SimpleModelParserXML simpleModelParser = new SimpleModelParserXML(
143+
modelLoader, getMetaDataClassLoader(), sourceURI.toString());
144+
simpleModelParser.loadAndMerge(this, sourceURI);
145+
}
146+
}
147+
148+
// Only occurs if no sourceURIs were loaded
149+
if ( !typesLoaded ) loadDefaultSimpleTypes();
150+
151+
// Validate the MetaData
152+
validate();
153+
154+
return this;
155+
}
156+
157+
protected void loadDefaultSimpleTypes() {
158+
SimpleTypesParserXML simpleTypesParser = new SimpleTypesParserXML(
159+
getTypesLoader(),
160+
getMetaDataClassLoader(),
161+
SIMPLE_TYPES_XML );
162+
simpleTypesParser.loadAndMerge( this, URIHelper.toURI("types:resource:"+SIMPLE_TYPES_XML));
163+
}
164+
165+
/*protected InputStream getResourceInputStream(String resource) throws FileNotFoundException {
166+
167+
InputStream is = null;
168+
File f = new File(resource);
169+
if (!f.exists()) {
170+
is = this.getClass().getClassLoader().getResourceAsStream(resource);
171+
} else {
172+
is = new FileInputStream(f);
173+
}
174+
return is;
175+
}*/
176+
}
177+
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.draagon.meta.loader.simple.xml;
2+
3+
import com.draagon.meta.MetaDataException;
4+
import com.draagon.meta.io.object.xml.XMLObjectReader;
5+
import com.draagon.meta.loader.model.MetaModel;
6+
import com.draagon.meta.loader.model.MetaModelLoader;
7+
import com.draagon.meta.loader.model.MetaModelParser;
8+
import com.draagon.meta.loader.types.TypesConfig;
9+
import com.draagon.meta.loader.uri.URIHelper;
10+
11+
import java.io.IOException;
12+
import java.io.InputStream;
13+
import java.net.URI;
14+
15+
public class SimpleModelParserXML extends MetaModelParser<TypesConfig,SimpleLoaderXML,URI> {
16+
17+
protected SimpleModelParserXML(MetaModelLoader modelLoader, ClassLoader classLoader, String sourceName) {
18+
super(modelLoader, classLoader, sourceName);
19+
}
20+
21+
@Override
22+
public void loadAndMerge( SimpleLoaderXML intoLoader, URI uri) {
23+
24+
InputStream is = null;
25+
try {
26+
is = URIHelper.getInputStream( uri );
27+
//intoLoader.getResourceInputStream(resource);
28+
loadAndMergeFromStream( intoLoader, is );
29+
}
30+
catch( IOException e ) {
31+
throw new MetaDataException( "Unable to load URI ["+uri+"]: " + e.getMessage(), e );
32+
}
33+
finally {
34+
try {
35+
if ( is != null ) is.close();
36+
} catch( IOException e ) {
37+
throw new MetaDataException( "Unable to close URI ["+uri+"]: " + e.getMessage(), e );
38+
}
39+
}
40+
}
41+
42+
/* Load MetaDataModel Stream */
43+
public void loadAndMergeFromStream( SimpleLoaderXML intoLoader, InputStream in ) {
44+
45+
IOException ioEx = null;
46+
47+
MetaModel metadata = null;
48+
XMLObjectReader reader = null;
49+
50+
try {
51+
reader = new XMLObjectReader( getLoader(), in );
52+
metadata = (MetaModel) reader.read( getLoader().getMetaObjectByName(MetaModel.OBJECT_NAME));
53+
} catch (IOException e) {
54+
ioEx = e;
55+
}
56+
57+
try {
58+
reader.close();
59+
} catch (IOException ex) {
60+
if ( ioEx != null ) ioEx = ex;
61+
}
62+
if ( ioEx != null ) throw new MetaDataException( "Error loading MetaData from "+
63+
"["+getSourcename()+"]: "+ ioEx.toString(), ioEx );
64+
65+
// Parse MetaData and Construct MetaData types
66+
mergeMetaDataModel( intoLoader, metadata );
67+
}
68+
}

0 commit comments

Comments
 (0)