Reading JSON-String using EMFJson - java

I am using EMFJson for serializing EMF Ecore Models. I am able to create a JSON String from an existing model. However, the way back is not working for me. I tried the following two snippets:
First Attempt:
ObjectMapper objectMapper = EMFModule.setupDefaultMapper();
objectMapper.reader().forType(MyClass.class).readValue(string);
Second Attempt:
ObjectMapper objectMapper = EMFModule.setupDefaultMapper();
ResourceSet resourceSet = new ResourceSetImpl();
resourceSet.getResourceFactoryRegistry()
.getExtensionToFactoryMap()
.put("json", new JsonResourceFactory());
try {
Resource resource = objectMapper
.reader()
.withAttribute(EMFContext.Attributes.RESOURCE_SET, resourceSet)
.withAttribute(EMFContext.Attributes.RESOURCE_URI, null)
.forType(Resource.class)
.readValue(string);
} catch (IOException e1) {
e1.printStackTrace();
}
For both attempts I am getting the following exception: java.lang.RuntimeException: Cannot create resource for uri default
I guess that the second approach cannot work at all as I do not know what to provide as RESOURCE_URI. The example here I took as foundation for attempt two reads a file rather than a string. Does somebody have an idea how to make this work? Thanks!

I managed to handle it using the answer given here: Parse XML in string format using EMF
The method with my changes looks like this:
private EObject loadEObjectFromString(String model, EPackage ePackage) throws IOException {
ResourceSet resourceSet = new ResourceSetImpl();
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(Resource.Factory.Registry.DEFAULT_EXTENSION, new JsonResourceFactory());
resourceSet.getPackageRegistry().put(ePackage.getNsURI(), ePackage);
Resource resource = resourceSet.createResource(URI.createURI("*.extension"));
InputStream stream = new ByteArrayInputStream(model.getBytes(StandardCharsets.UTF_8));
resource.load(stream, null);
return resource.getContents().get(0);
}
Now I can call it like this:
EObject test = this.loadEObjectFromString(jsonString, MyPackage.eINSTANCE);

Related

I'm trying to deserialize an XML and getting null for some of the attributes

I'm trying to deserialize the below XML to an object, but one of the values (Required)is returning null.
<?xml version="1.0" encoding="UTF-8"?>
-<sy:config xmlns:sy="http://www.example.com/def/sy">
-<sy:configurations>
-<sy:configuration property="isReq" name="ABC">
**Required**
<atom:link title="ABC Uri" xmlns:atom="http://www.w3.org/2005/Atom" rel="http://www.example.com/def//id"
href="abc/bc/def/docid"/>
</sy:configuration>
</sy:configurations>
</sy:config>
enter code here
I'm using the below code to deserialize eclipse emfutil to deserialize could you please let me know why the configuration.getvalue() is returning null instead of returning 'Required'
private static <T extends EObject> T readEObjectFromInputStream(InputStream inputStream, String emfFileExtension,Class<T> expectedResultType) throws IOException {
org.eclipse.emf.common.util.URI emfResourceUri = org.eclipse.emf.common.util.URI
.createPlatformResourceURI(FILE_PATH + emfFileExtension, true);
Resource emfResource = new ResourceSetImpl().createResource(emfResourceUri);
emfResource.load(inputStream, null);
EObject eObject = emfResource.getContents().get(0);
T result = expectedResultType.cast(eObject);
return result;
}
This post on the Eclipse forums has an example of how to do this, and a discussion of several reasons why it might not be working.
Here's the full example:
try { ResourceSet resourceSet = new ResourceSetImpl();
Resource resource = resourceSet.createResource(URI.createURI("http:///My.chbasev21"));
DocumentRoot documentRoot = ChbaseV21Factory.eINSTANCE.createDocumentRoot();
CompanyDetailsType root = ChbaseV21Factory.eINSTANCE.createCompanyDetailsType();
documentRoot.setCompanyDetails(root);
resource.getContents().add(documentRoot);
//resource.save(Collections.EMPTY_MAP);
resource.save(System.out, null);
resource.save(new FileOutputStream("C:/test2.xml"), null);
}
catch (IOException exception) {
exception.printStackTrace();
}

How to parse a big rdf file in rdf4j

I want to parse a huge file in RDF4J using the following code but I get an exception due to parser limit;
public class ConvertOntology {
public static void main(String[] args) throws RDFParseException, RDFHandlerException, IOException {
String file = "swetodblp_april_2008.rdf";
File initialFile = new File(file);
InputStream input = new FileInputStream(initialFile);
RDFParser parser = Rio.createParser(RDFFormat.RDFXML);
parser.setPreserveBNodeIDs(true);
Model model = new LinkedHashModel();
parser.setRDFHandler(new StatementCollector(model));
parser.parse(input, initialFile.getAbsolutePath());
FileOutputStream out = new FileOutputStream("swetodblp_april_2008.nt");
RDFWriter writer = Rio.createWriter(RDFFormat.TURTLE, out);
try {
writer.startRDF();
for (Statement st: model) {
writer.handleStatement(st);
}
writer.endRDF();
}
catch (RDFHandlerException e) {
}
finally {
out.close();
}
}
The parser has encountered more than "100,000" entity expansions in this document; this is the limit imposed by the application.
I execute my code as following as suggested on the RDF4J web site to set up the two parameters (as in the following command)
mvn -Djdk.xml.totalEntitySizeLimit=0 -DentityExpansionLimit=0 exec:java
any help please
The error is due to the Apache Xerces XML parser, rather than the default JDK XML parser.
So Just delete Xerces XML folder from you .m2 repository and the code works fine.

Unable to attach file to issue in jira via rest api Java

I want to attach multiple files to issue. I'm able to create issue successfully however i am facing problem in attaching documents after creating issue. I have referred to this link SOLVED: attach a file using REST from scriptrunner
I am getting 404 error even though issue exists and also user has all the permissions.
File fileToUpload = new File("D:\\dummy.txt");
InputStream in = null;
try {
in = new FileInputStream(fileToUpload);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
HttpResponse < String > response3 = Unirest
.post("https://.../rest/api/2/issue/test-85/attachments")
.basicAuth(username, password).field("file", in , "dummy.txt")
.asString();
System.out.println(response3.getStatus());
here test-85 is a issueKey value.
And i am using open-unirest-java-3.3.06.jar. Is the way i am attaching documents is correct?
I am not sure how open-unirest manages its fields, maybe it tries to put them as json field, rather than post content.
I've been using Rcarz's Jira client. It's a little bit outdated but it still works.
Maybe looking at its code will help you, or you can just use it directly.
The Issue class:
public JSON addAttachment(File file) throws JiraException {
try {
return restclient.post(getRestUri(key) + "/attachments", file);
} catch (Exception ex) {
throw new JiraException("Failed add attachment to issue " + key, ex);
}
}
And in RestClient class:
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
public JSON post(String path, File file) throws RestException, IOException, URISyntaxException {
return request(new HttpPost(buildURI(path)), file);
}
private JSON request(HttpEntityEnclosingRequestBase req, File file) throws RestException, IOException {
if (file != null) {
File fileUpload = file;
req.setHeader("X-Atlassian-Token", "nocheck");
MultipartEntity ent = new MultipartEntity();
ent.addPart("file", new FileBody(fileUpload));
req.setEntity(ent);
}
return request(req);
}
So I'm not sure why you're getting a 404, Jira is sometime fuzzy and not really clear about its error, try printing the full error, or checking Jira's log if you can. Maybe it's just the "X-Atlassian-Token", "nocheck", try adding it.

Error on load EMF model dynamically

I am following the article http://www.ibm.com/developerworks/library/os-eclipse-dynamicemf/ to load dynamically metamodels.
I load the model instanced document using this
ResourceSet load_resourceSet = new ResourceSetImpl();
// ResourceSet load_resourceSet2 = new ResourceSetImpl();
/*
* Register XMI Factory impl ementation using DEFAULT_EXTENSION
*/
load_resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*", //$NON-NLS-1$
new XMIResourceFactoryImpl());
/*
* Add bookStoreEPackage to package registry
*/
load_resourceSet.getPackageRegistry().put("http:///com.ibm.dynamic.example.bookstore.ecore",
bookStoreEPackage);
// load_resourceSet2.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*", //$NON-NLS-1$
// new XMIResourceFactoryImpl());
/*
* Load the resources using the URI
*/
Resource modelo_esquerda = load_resourceSet
.getResource(URI.createURI("./BookStore.xmi"), true);
But, I´ve got this error message
Exception in thread "main" org.eclipse.emf.ecore.resource.impl.ResourceSetImpl$1DiagnosticWrappedException: org.eclipse.emf.ecore.xmi.ClassNotFoundException: Class 'BookStore' is not found or is abstract. (.\BookStore.xmi, 9, 34)
The XMI file already exists on directory.
What I can do?
Thank you
You can try the following, it worked well for me:
XMIResourceImpl resource = new XMIResourceImpl();
File source = new File(xmlName.xml);
resource.load(new FileInputStream(source), new HashMap<Object,Object>());
Data data = (Data) resource.getContents().get(0);
Where Data is your model.

How to validate an XML file against an XSD file?

I'm generating some xml files that needs to conform to an xsd file that was given to me. How should I verify they conform?
The Java runtime library supports validation. Last time I checked this was the Apache Xerces parser under the covers. You should probably use a javax.xml.validation.Validator.
import javax.xml.XMLConstants;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.*;
import java.net.URL;
import org.xml.sax.SAXException;
//import java.io.File; // if you use File
import java.io.IOException;
...
URL schemaFile = new URL("http://host:port/filename.xsd");
// webapp example xsd:
// URL schemaFile = new URL("http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd");
// local file example:
// File schemaFile = new File("/location/to/localfile.xsd"); // etc.
Source xmlFile = new StreamSource(new File("web.xml"));
SchemaFactory schemaFactory = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
try {
Schema schema = schemaFactory.newSchema(schemaFile);
Validator validator = schema.newValidator();
validator.validate(xmlFile);
System.out.println(xmlFile.getSystemId() + " is valid");
} catch (SAXException e) {
System.out.println(xmlFile.getSystemId() + " is NOT valid reason:" + e);
} catch (IOException e) {}
The schema factory constant is the string http://www.w3.org/2001/XMLSchema which defines XSDs. The above code validates a WAR deployment descriptor against the URL http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd but you could just as easily validate against a local file.
You should not use the DOMParser to validate a document (unless your goal is to create a document object model anyway). This will start creating DOM objects as it parses the document - wasteful if you aren't going to use them.
Here's how to do it using Xerces2. A tutorial for this, here (req. signup).
Original attribution: blatantly copied from here:
import org.apache.xerces.parsers.DOMParser;
import java.io.File;
import org.w3c.dom.Document;
public class SchemaTest {
public static void main (String args[]) {
File docFile = new File("memory.xml");
try {
DOMParser parser = new DOMParser();
parser.setFeature("http://xml.org/sax/features/validation", true);
parser.setProperty(
"http://apache.org/xml/properties/schema/external-noNamespaceSchemaLocation",
"memory.xsd");
ErrorChecker errors = new ErrorChecker();
parser.setErrorHandler(errors);
parser.parse("memory.xml");
} catch (Exception e) {
System.out.print("Problem parsing the file.");
}
}
}
We build our project using ant, so we can use the schemavalidate task to check our config files:
<schemavalidate>
<fileset dir="${configdir}" includes="**/*.xml" />
</schemavalidate>
Now naughty config files will fail our build!
http://ant.apache.org/manual/Tasks/schemavalidate.html
Since this is a popular question, I will point out that java can also validate against "referred to" xsd's, for instance if the .xml file itself specifies XSD's in the header, using xsi:schemaLocation or xsi:noNamespaceSchemaLocation (or xsi for particular namespaces) ex:
<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.example.com/document.xsd">
...
or schemaLocation (always a list of namespace to xsd mappings)
<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.com/my_namespace http://www.example.com/document.xsd">
...
The other answers work here as well, because the .xsd files "map" to the namespaces declared in the .xml file, because they declare a namespace, and if matches up with the namespace in the .xml file, you're good. But sometimes it's convenient to be able to have a custom resolver...
From the javadocs: "If you create a schema without specifying a URL, file, or source, then the Java language creates one that looks in the document being validated to find the schema it should use. For example:"
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Schema schema = factory.newSchema();
and this works for multiple namespaces, etc.
The problem with this approach is that the xmlsns:xsi is probably a network location, so it'll by default go out and hit the network with each and every validation, not always optimal.
Here's an example that validates an XML file against any XSD's it references (even if it has to pull them from the network):
public static void verifyValidatesInternalXsd(String filename) throws Exception {
InputStream xmlStream = new new FileInputStream(filename);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(true);
factory.setNamespaceAware(true);
factory.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
"http://www.w3.org/2001/XMLSchema");
DocumentBuilder builder = factory.newDocumentBuilder();
builder.setErrorHandler(new RaiseOnErrorHandler());
builder.parse(new InputSource(xmlStream));
xmlStream.close();
}
public static class RaiseOnErrorHandler implements ErrorHandler {
public void warning(SAXParseException e) throws SAXException {
throw new RuntimeException(e);
}
public void error(SAXParseException e) throws SAXException {
throw new RuntimeException(e);
}
public void fatalError(SAXParseException e) throws SAXException {
throw new RuntimeException(e);
}
}
You can avoid pulling referenced XSD's from the network, even though the xml files reference url's, by specifying the xsd manually (see some other answers here) or by using an "XML catalog" style resolver. Spring apparently also can intercept the URL requests to serve local files for validations. Or you can set your own via setResourceResolver, ex:
Source xmlFile = new StreamSource(xmlFileLocation);
SchemaFactory schemaFactory = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema();
Validator validator = schema.newValidator();
validator.setResourceResolver(new LSResourceResolver() {
#Override
public LSInput resolveResource(String type, String namespaceURI,
String publicId, String systemId, String baseURI) {
InputSource is = new InputSource(
getClass().getResourceAsStream(
"some_local_file_in_the_jar.xsd"));
// or lookup by URI, etc...
return new Input(is); // for class Input see
// https://stackoverflow.com/a/2342859/32453
}
});
validator.validate(xmlFile);
See also here for another tutorial.
I believe the default is to use DOM parsing, you can do something similar with SAX parser that is validating as well saxReader.setEntityResolver(your_resolver_here);
Using Java 7 you can follow the documentation provided in package description.
// create a SchemaFactory capable of understanding WXS schemas
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
// load a WXS schema, represented by a Schema instance
Source schemaFile = new StreamSource(new File("mySchema.xsd"));
Schema schema = factory.newSchema(schemaFile);
// create a Validator instance, which can be used to validate an instance document
Validator validator = schema.newValidator();
// validate the DOM tree
try {
validator.validate(new StreamSource(new File("instance.xml"));
} catch (SAXException e) {
// instance document is invalid!
}
If you have a Linux-Machine you could use the free command-line tool SAXCount. I found this very usefull.
SAXCount -f -s -n my.xml
It validates against dtd and xsd.
5s for a 50MB file.
In debian squeeze it is located in the package "libxerces-c-samples".
The definition of the dtd and xsd has to be in the xml! You can't config them separately.
With JAXB, you could use the code below:
#Test
public void testCheckXmlIsValidAgainstSchema() {
logger.info("Validating an XML file against the latest schema...");
MyValidationEventCollector vec = new MyValidationEventCollector();
validateXmlAgainstSchema(vec, inputXmlFileName, inputXmlSchemaName, inputXmlRootClass);
assertThat(vec.getValidationErrors().isEmpty(), is(expectedValidationResult));
}
private void validateXmlAgainstSchema(final MyValidationEventCollector vec, final String xmlFileName, final String xsdSchemaName, final Class<?> rootClass) {
try (InputStream xmlFileIs = Thread.currentThread().getContextClassLoader().getResourceAsStream(xmlFileName);) {
final JAXBContext jContext = JAXBContext.newInstance(rootClass);
// Unmarshal the data from InputStream
final Unmarshaller unmarshaller = jContext.createUnmarshaller();
final SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
final InputStream schemaAsStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(xsdSchemaName);
unmarshaller.setSchema(sf.newSchema(new StreamSource(schemaAsStream)));
unmarshaller.setEventHandler(vec);
unmarshaller.unmarshal(new StreamSource(xmlFileIs), rootClass).getValue(); // The Document class is the root object in the XML file you want to validate
for (String validationError : vec.getValidationErrors()) {
logger.trace(validationError);
}
} catch (final Exception e) {
logger.error("The validation of the XML file " + xmlFileName + " failed: ", e);
}
}
class MyValidationEventCollector implements ValidationEventHandler {
private final List<String> validationErrors;
public MyValidationEventCollector() {
validationErrors = new ArrayList<>();
}
public List<String> getValidationErrors() {
return Collections.unmodifiableList(validationErrors);
}
#Override
public boolean handleEvent(final ValidationEvent event) {
String pattern = "line {0}, column {1}, error message {2}";
String errorMessage = MessageFormat.format(pattern, event.getLocator().getLineNumber(), event.getLocator().getColumnNumber(),
event.getMessage());
if (event.getSeverity() == ValidationEvent.FATAL_ERROR) {
validationErrors.add(errorMessage);
}
return true; // you collect the validation errors in a List and handle them later
}
}
One more answer: since you said you need to validate files you are generating (writing), you might want to validate content while you are writing, instead of first writing, then reading back for validation. You can probably do that with JDK API for Xml validation, if you use SAX-based writer: if so, just link in validator by calling 'Validator.validate(source, result)', where source comes from your writer, and result is where output needs to go.
Alternatively if you use Stax for writing content (or a library that uses or can use stax), Woodstox can also directly support validation when using XMLStreamWriter. Here's a blog entry showing how that is done:
If you are generating XML files programatically, you may want to look at the XMLBeans library. Using a command line tool, XMLBeans will automatically generate and package up a set of Java objects based on an XSD. You can then use these objects to build an XML document based on this schema.
It has built-in support for schema validation, and can convert Java objects to an XML document and vice-versa.
Castor and JAXB are other Java libraries that serve a similar purpose to XMLBeans.
Using Woodstox, configure the StAX parser to validate against your schema and parse the XML.
If exceptions are caught the XML is not valid, otherwise it is valid:
// create the XSD schema from your schema file
XMLValidationSchemaFactory schemaFactory = XMLValidationSchemaFactory.newInstance(XMLValidationSchema.SCHEMA_ID_W3C_SCHEMA);
XMLValidationSchema validationSchema = schemaFactory.createSchema(schemaInputStream);
// create the XML reader for your XML file
WstxInputFactory inputFactory = new WstxInputFactory();
XMLStreamReader2 xmlReader = (XMLStreamReader2) inputFactory.createXMLStreamReader(xmlInputStream);
try {
// configure the reader to validate against the schema
xmlReader.validateAgainst(validationSchema);
// parse the XML
while (xmlReader.hasNext()) {
xmlReader.next();
}
// no exceptions, the XML is valid
} catch (XMLStreamException e) {
// exceptions, the XML is not valid
} finally {
xmlReader.close();
}
Note: If you need to validate multiple files, you should try to reuse your XMLInputFactory and XMLValidationSchema in order to maximize the performance.
Are you looking for a tool or a library?
As far as libraries goes, pretty much the de-facto standard is Xerces2 which has both C++ and Java versions.
Be fore warned though, it is a heavy weight solution. But then again, validating XML against XSD files is a rather heavy weight problem.
As for a tool to do this for you, XMLFox seems to be a decent freeware solution, but not having used it personally I can't say for sure.
Validate against online schemas
Source xmlFile = new StreamSource(Thread.currentThread().getContextClassLoader().getResourceAsStream("your.xml"));
SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = factory.newSchema(Thread.currentThread().getContextClassLoader().getResource("your.xsd"));
Validator validator = schema.newValidator();
validator.validate(xmlFile);
Validate against local schemas
Offline XML Validation with Java
I had to validate an XML against XSD just one time, so I tried XMLFox. I found it to be very confusing and weird. The help instructions didn't seem to match the interface.
I ended up using LiquidXML Studio 2008 (v6) which was much easier to use and more immediately familiar (the UI is very similar to Visual Basic 2008 Express, which I use frequently). The drawback: the validation capability is not in the free version, so I had to use the 30 day trial.

Categories

Resources