I have the next Java code:
public static <T> T buildSAMLObject(final Class<T> clazz) {
T object = null;
try {
XMLObjectBuilderFactory builderFactory = XMLObjectProviderRegistrySupport.getBuilderFactory();
QName defaultElementName = (QName)clazz.getDeclaredField("DEFAULT_ELEMENT_NAME").get(null);
object = (T)builderFactory.getBuilder(defaultElementName).buildObject(defaultElementName);
} catch (IllegalAccessException e) {
throw new IllegalArgumentException("Could not create SAML object");
} catch (NoSuchFieldException e) {
throw new IllegalArgumentException("Could not create SAML object");
}
return object;
}
I am trying to convert it to Scala and so far I got:
def buildSAMLObject(clazz: asInstanceOf[T]): [T] T {
var obj = builderFactory.getBuilder(defaultElementName).buildObject(defaultElementName).asInstanceOf[T];
try {
val builderFactory = XMLObjectProviderRegistrySupport.getBuilderFactory();
val defaultElementName = clazz.getDeclaredField("DEFAULT_ELEMENT_NAME").get(null).asInstanceOf[QName];
obj = builderFactory.getBuilder(defaultElementName).buildObject(defaultElementName).asInstanceOf[T];
} catch
{
case e: IllegalAccessException => throw new IllegalArgumentException("Could not create SAML object")
case e: NoSuchFieldException => throw new IllegalArgumentException("Could not create SAML object")
}
obj
}
The latter is not compiling and I believe this is because I do not know how to represent [T] T. Any suggestions, please?
Generics in method signature causes the error, it should go like this:
def buildSAMLObject[T](clazz: Class[T]): T = {
P.S.: In scala newline sumbol is an equivalent of semicolon, you don't need to write them.
Related
I'm having trouble converting a List object and it's returning the error below:
expected S in value {L: [{M: {txt_just={S: new client,}, num_funl={S: 123,}, num_propt={S: 2f1a8e6c-68bb-4c26-9326-3823d9f96c4c,}, ind_decs={S: S,}, dat_hor={S: 20220721183000,}},}],}
My Class translator:
public class ObjectTranslators<T> implements DynamoDBTypeConverter<String, T> {
private static final ObjectMapper mapper = new ObjectMapper();
#Override
public String convert(T t) {
try {
return mapper.writeValueAsString(t);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException("Unable to parse JSON");
}
}
#Override
public T unconvert(String s) {
try {
return mapper.readValue(s, new TypeReference<>() {});
} catch (IOException e) {
throw new IllegalArgumentException("Unable to read JSON");
}
}
}
You are trying to convert a List that has a single entry which is a Map of 5 key/value pairs. Your real issue is probably that there is no value supplied to ind_decs but, it's also possible that you aren't properly using the expected generic T type wherever ObjectTranslators is used as well.
expected S in value
{
L: [
{
M: {
txt_just={S: new client,},
num_funl={S: 123,},
num_propt={S: 2f1a8e6c-68bb-4c26-9326-3823d9f96c4c,},
ind_decs={S: S,},
dat_hor={S: 20220721183000,}
},
}
],
}
So I'm working with JSON in Java and JSON can have a base of either an Array or an Object. In my Config class, I take a class as an argument so I can create the file accordingly if it doesn't exist. I also store the class as a private field so I know in future.
However, when I get to reading the file, I'd prefer to have multiple return types though the same method name. If I return Object, I then have to cast the returned value which I want to avoid.
Current code:
public class Config {
private File dir = null;
private File file = null;
private Class clazz = null;
public Config(String program, String fileName, Class root) throws IOException {
this.dir = new File(System.getProperty("user.home") + File.separator + program);
if (!this.dir.exists()) {
this.dir.mkdir();
}
this.file = new File(this.dir + File.separator + fileName);
if (!this.file.exists()) {
this.file.createNewFile();
if (root.getName().equals(JSONArray.class.getName())) {
Files.write(this.file.toPath(), "[]".getBytes());
} else if (root.getName().equals(JSONObject.class.getName())) {
Files.write(this.file.toPath(), "{}".getBytes());
}
}
this.clazz = root;
}
public JSONArray readConfig() {
return null;
}
public JSONObject readConfig() {
return null;
}
}
Is there anyway I can do what I want without having to return Object?
multiple return types though the same method name
well, it is possible to use generic function to achieve that. For example,
public static void main(String[] args) {
try {
String t = getObject(String.class);
Integer d = getObject(Integer.class);
} catch (Exception e) {
e.printStackTrace();
}
}
public static <T> T getObject(Class<T> returnType) throws Exception {
if(returnType == String.class) {
return (T) "test";
} else if(returnType == Integer.class) {
return (T) new Integer(0);
} else {
return (T) returnType.newInstance();
}
}
Will the following code even compile?
I'm afraid no. There are few compilation errors such as
public Object readConfig() {
try {
// Assume jsonString exists
return (this.clazz.getDeclaredConstructor(String.class).newInstance(jsonString)); <--- clazz should be getClass()
} catch (InstantiationException | IllegalAccessException
| IllegalArgumentException | InvocationTargetException
| NoSuchMethodException | SecurityException e) {
e.printStackTrace();
<---- missing return statement
}
}
I am using OWLIM-lite (5.2) for owl2rl ontology reasoning. Storing of axioms seems to work, repository initialized, but the system does not infer any implicit statements (when I query number of implicit statements, the system returns 0).
I also tried to query the repository, the system returned only explicit knowledge. When I serialized the ontology into RDF/XML and reasoned it in Protege using Pellet, the it successfully returned expected (implicit+explicit) values.
Thanks for any suggestions.
Config:
[] a rep:Repository ;
rep:repositoryID "example" ;
rdfs:label "OWLIM Getting Started" ;
rep:repositoryImpl [
rep:repositoryType "openrdf:SailRepository" ;
sr:sailImpl [
sail:sailType "swiftowlim:Sail" ;
owlim:repository-type "in-memory-repository" ;
owlim:ruleset "owl2-rl-reduced-optimized" ;
# owlim:storage-folder "storage" ;
# OWLIM-SE parameters
owlim:cache-memory "180m" ;
# OWLIM-Lite parameters
owlim:noPersist "true" ;
owlim:jobsize "1000" ;
owlim:new-triples-file "new"
]
].
Repository initialization:
private OwlimRepository() throws RepositoryException, RepositoryConfigException, RDFParseException, RDFHandlerException, IOException {
repositoryManager = new LocalRepositoryManager(new File("."));
repositoryManager.initialize();
Graph repositoryRdfDescription = parseFile(new File(this.getClass().getClassLoader().getResource("owlim.ttl").getFile()), RDFFormat.TURTLE, "http://example.org#");
Iterator<Statement> iter = repositoryRdfDescription.match(null, RDF.TYPE, new URIImpl(
"http://www.openrdf.org/config/repository#Repository"));
Resource repositoryNode = null;
if (iter.hasNext()) {
Statement st = iter.next();
repositoryNode = st.getSubject();
}
RepositoryConfig repositoryConfig = RepositoryConfig.create(repositoryRdfDescription,
repositoryNode);
repositoryManager.addRepositoryConfig(repositoryConfig);
repository = repositoryManager.getRepository("example");
repository.initialize();
valueFactory = repository.getValueFactory();
repositoryConnection = repository.getConnection();
repositoryConnection.setAutoCommit(false);
}
How am I loading the ontology:
public void setRepository(OwlimRepository repository) {
try {
this.repository = repository;
final RDFInserter inserter = new RDFInserter(repository.getRepository().getConnection());
RDFParser parser = Rio.createParser(RDFFormat.RDFXML);
parser.setRDFHandler(new RDFHandler() {
public void startRDF() throws RDFHandlerException {
inserter.startRDF();
}
public void endRDF() throws RDFHandlerException {
inserter.endRDF();
}
public void handleNamespace(String string, String string1) throws RDFHandlerException {
inserter.handleNamespace(string, string1);
}
public void handleStatement(Statement stmnt) throws RDFHandlerException {
try {
System.out.println("inserting: " + stmnt);
inserter.handleStatement(stmnt);
OwlimSparqlProcessor.this.repository.getRepositoryConnection().commit();
} catch (RepositoryException ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
}
public void handleComment(String string) throws RDFHandlerException {
inserter.handleComment(string);
}
});
parser.parse(new BufferedInputStream(new FileInputStream(OwlimSparqlProcessor.class.getClassLoader().getResource("odra-ontology.owl").getFile())), OntologyConstants.ODRA_ONTOLOGY_BASE);
} catch (Exception ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
}
New knowledge storing:
private void addStatement(URI subject, URI property, URI object) {
try {
repositoryConnection.add(subject, property, object);
repositoryConnection.commit();
} catch (RepositoryException ex) {
throw new RuntimeException(ex);
}
}
Finally found the issue. The config is OK, mistake was in the ontology. OWL2RL does not support superclass in a form of (X or Y), hence OWLIM did not reason it. Since Pellet is DL and has this feature, it reasoned as expected.
I thought that owlim will check the conformance, but it does not. So if you run into simillar issue try first this profile validator.
I'm sorry it was surely already asked, but I did not find what I need
I have several message types:
class AbstractMessage {
int code;
String token;
}
class ShareMessage extends AbstractMessage{
String user;
Map<String, String> friends;
}
class PostMessage extends AbstractMessage{
String user;
Map<String, String> data;
}
and a method to decode them from the json post message:
public Object getMessage(BufferedReader r, Type t){
Object o = null;
try{
o = g.fromJson(r, t);
} catch (final JsonSyntaxException e) {
LOGGER.info("Error in Json format", e);
} catch (final JsonParseException e) {
LOGGER.info("Error in parsing Json", e);
}
return o;
}
then for example:
Type dataType = new TypeToken<PostMessage>() {}.getType();
PostMessage m = (PostMessage) getMessage(request.getReader(), dataType);
works, but it's ugly, how can I have a parametrized getMessage function, or anything better than returning Object and casting
thx
Add <T> to the method signature, immediately before the return type. This creates a type-parameterized method:
public <T> T getMessage(BufferedReader r, TypeToken<T> typeToken){
try {
return g.fromJson(r, typeToken.getType());
} catch (final JsonSyntaxException e) {
LOGGER.info("Error in Json format", e);
} catch (final JsonParseException e) {
LOGGER.info("Error in parsing Json", e);
}
return null;
}
Call it like this:
PostMessage m = getMessage(request.getReader(), new TypeToken<PostMessage>() {});
world! I need to instantiate an Object from the name of its Class. I know that it is possible to do it, this way
MyObject myObject = null;
try {
Constructor constructor = Class.forName( "fully.qualified.class.name" ).getConstructor(); // Get the constructor without parameters
myObject = (MyObject) constructor.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
The problem is that the name of my class is not fully qualified. Is there a way to get the complete name by only knowing the short name?
MyObject myObject = null;
for (Package p : Package.getPackages()) {
try {
myObject = Class.forName(p.getName() + "." + className).newInstance();
break;
} catch (ClassNotFoundException ex) {
// ignore
}
}
The Package.getPackages() call will give you every package known to the current classes ClassLoader and its ancestors.
Warning: this will be expensive because you are repeatedly throwing and catching exceptions. It may be possible to speed it up by testing:
this.getClass().getClassLoader().findResource(binaryClassName) != null
before calling Class.forName(...) or the equivalent.
Try this repeatedly for a package search path. ;)
String[] packages = ...;
String className = ...;
MyObject myObject = null;
for(String p : packages)
try {
myObject = Class.forName(p + '.' + className).newInstance();
break;
} catch (Exception ignored) {
}