Orient DB - Export subclasses of a specified class using JAVA - java

Im working with exporting and importing Orient DB using java. I could export a whole database. But when i specify to export a specified class it export that class only. Sub classes are not exported. Here is the code:
ODatabaseDocumentTx db = new ODatabaseDocumentTx("remote:localhost/sampleDataBase").open("admin", "admin");
ODatabaseExport export = new ODatabaseExport(db, "DataCont/FinalTry.gz", listener);
Set<String> a= new HashSet<String>();
a.add("Employee".toUpperCase());
export.setIncludeClasses(a);
export.exportDatabase();
export.close();
So is this suppose to be or am i doing anything wrong?

Checking the source code for ODatabaseExport it does seem that it only takes clusters/records which are exactly of the type specified with setIncludeClasses(). For instance in exportRecords():
ODocument doc = (ODocument) rec;
final String className = doc.getClassName() != null ? doc.getClassName().toUpperCase() : null;
if (includeClasses != null) {
if (!includeClasses.contains(className))
continue;
} else if (excludeClasses != null) {
if (excludeClasses.contains(className))
continue;
}
They have similar checks in several other places in that class. This would mean that you need to put into the a set all the classes you want to export yourself.

You can add this piece of code if want to export all subclasses too:
Set<String> classesToExport = new HashSet<>();
classesToExport.add("Employee".toUpperCase());
OSchema oSchema = db.getMetadata().getSchema();
for (String className : classesToExport) {
OClass clazz = oSchema.getClass(className);
for(OClass subClass : clazz.getAllBaseClasses()){
//String subClassName = subClass.getName();
String subClassName = subClass.getName().toUpperCase();
if(!classesToExport.contains(subClassName)){
classesToExport.add(subClassName);
}
}
}

Related

Using ElasticSearch's script_upsert to create a document

According to the official documentation Update API - Upserts one can use scripted_upsert in order to handle update (for existing document) or insert (for new document) form within the script. The thing is they never show how the script should look to do that. The Java - Update API Doesn't have any information on the ScriptUpsert uses.
This is the code I'm using:
//My function to build and use the upsert
public void scriptedUpsert(String key, String parent, String scriptSource, Map<String, ? extends Object> parameters) {
Script script = new Script(scriptSource, ScriptType.INLINE, null, parameters);
UpdateRequest request = new UpdateRequest(index, type, key);
request.scriptedUpsert(true);
request.script(script);
if (parent != null) {
request.parent(parent);
}
this.bulkProcessor.add(request);
}
//A test call to validate the function
String scriptSource = "if (!ctx._source.hasProperty(\"numbers\")) {ctx._source.numbers=[]}";
Map<String, List<Integer>> parameters = new HashMap<>();
List<Integer> numbers = new LinkedList<>();
numbers.add(100);
parameters.put("numbers", numbers);
bulk.scriptedUpsert("testUser", null, scriptSource, parameters);
And I'm getting the following exception when "testUser" documents doesn't exists:
DocumentMissingException[[user][testUser]: document missing
How can I make the scriptUpsert work from the Java code?
This is how a scripted_upsert command should look like (and its script):
POST /sessions/session/1/_update
{
"scripted_upsert": true,
"script": {
"inline": "if (ctx.op == \"create\") ctx._source.numbers = newNumbers; else ctx._source.numbers += updatedNumbers",
"params": {
"newNumbers": [1,2,3],
"updatedNumbers": [55]
}
},
"upsert": {}
}
If you call the above command and the index doesn't exist, it will create it, together with the newNumbers values in the new documents. If you call again the exact same command the numbers values will become 1,2,3,55.
And in your case you are missing "upsert": {} part.
As Andrei suggested I was missing the upsert part, changing the function to:
public void scriptedUpsert(String key, String parent, String scriptSource, Map<String, ? extends Object> parameters) {
Script script = new Script(scriptSource, ScriptType.INLINE, null, parameters);
UpdateRequest request = new UpdateRequest(index, type, key);
request.scriptedUpsert(true);
request.script(script);
request.upsert("{}"); // <--- The change
if (parent != null) {
request.parent(parent);
}
this.bulkProcessor.add(request);
}
Fix it.

Can strange paths cause a wrong structure of the file system?

Consider the following example:
//both files are the same
final File path = new File("/home/alice/../bob/file.txt");
final File canonicalPath = new File("/home/bob/file.txt");
File parent = canonicalPath;
while((parent = parent.getParentFile()) != null) {
System.out.println(parent.getName());
}
This would print:
bob
home
If I would use path instead of canonicalPath, would the output be the same or would it be:
bob
home
alice
home
This woule be very strange because it would suggest that alice is the parent of home which is not true.
First of all, I think you want to compare home/alice/../bob/file.txt without a starting / instead of /home/alice/../bob/file.txt, otherwise you'd be comparing apples with oranges.
Actually it's more interesting to compare the difference using this code instead:
File parent;
parent = path;
while((parent = parent.getParentFile()) != null) {
System.out.println(parent);
}
parent = canonicalPath;
while((parent = parent.getParentFile()) != null) {
System.out.println(parent);
}
The parents of "home/alice/../bob/file.txt":
"home/alice/../bob"
"home/alice/.."
"home/alice"
"home"
null
In contrast, the parents of "home/bob/file.txt":
"home/bob"
"home"
null
The result would not be the same since those are two different filesystem paths.
But use Path instead:
final Path path = Paths.get("/home/bob/../alice/somefile");
final Path normalized = path.normalize(); // /home/alice/somefile
path.toAbsolutePath(); // get an absolute path
path.toRealPath(); // same, but follows symlinks
// etc etc

How to read XMP face data from JPEG in Java

I have saved Picasa's face data inside my JPEG files (in XMP) and now I am trying to read that information in Java. So far I am failing and help would be much appreciated.
I am trying to use metadata-extractor library (though any other solution would also be fine). I can read the basic information (like the date, the image size etc.), but I am lost at extracting the additional data. This is what I get so far:
File file -- this is my JPEG file
Metadata metadata = JpegMetadataReader.readMetadata(file);
XmpDirectory xmpDirectory = metadata.getDirectory(XmpDirectory.class);
XMPMeta xmpMeta = xmpDirectory.getXMPMeta();
System.out.println(xmpMeta.dumpObject());
Result:
ROOT NODE
http://www.metadataworkinggroup.com/schemas/regions/ = "mwg-rs:" (0x80000000 : SCHEMA_NODE)
mwg-rs:Regions (0x100 : STRUCT)
mwg-rs:AppliedToDimensions (0x100 : STRUCT)
stDim:h = "2793"
stDim:unit = "pixel"
stDim:w = "2047"
mwg-rs:RegionList (0x200 : ARRAY)
[1] (0x100 : STRUCT)
mwg-rs:Area (0x100 : STRUCT)
stArea:h = "0.69531"
stArea:unit = "normalized"
stArea:w = "0.790425"
stArea:x = "0.491451"
stArea:y = "0.41783"
mwg-rs:Name = "abcde"
mwg-rs:Type = "Face"
http://ns.adobe.com/xap/1.0/ = "xmp:" (0x80000000 : SCHEMA_NODE)
xmp:ModifyDate = "2014-04-06T19:43:24+01:00"
I do not understand how to get to these stArea:w, mwg-rs:Type = "Face", etc.
As usual, right after posting I've found a solution. I'll list it below to have it here.
try {
Metadata metadata = ImageMetadataReader.readMetadata(imageFile);
XmpDirectory xmpDirectory = metadata.getDirectory(XmpDirectory.class);
XMPMeta xmpMeta = xmpDirectory.getXMPMeta();
XMPIterator itr = xmpMeta.iterator();
while (itr.hasNext()) {
XMPPropertyInfo pi = (XMPPropertyInfo) itr.next();
if (pi != null && pi.getPath() != null) {
if ((pi.getPath().endsWith("stArea:w")) || (pi.getPath().endsWith("mwg-rs:Name")) || (pi.getPath().endsWith("stArea:h")))
System.out.println(pi.getValue().toString());
}
}
} catch (final NullPointerException npe) {
// ignore
}
What I do not like here is that it iterates through all properties instead of just reading the required ones. Any better (faster) solution?

Getting info from PsiMethod in Intellij IDEA plugin

I'm writing Intellij IDEA plugin for my project, and I've faced a problem - I cannot get some ingo about method (PsiMethod) from my code.
First, I want to know is this method public.
And second, I want to get fully-qualified names of the parameter classes. Currently I'm doing it like this:
method.getReturnTypeNoResolve().getInternalCanonicalText()
But it doesn't provide full name (with package name) for the standard JVM classes like String and List.
UPDATE First problem solved with the following code:
PsiUtil.getAccessLevel(method.getModifierList()) == PsiUtil.ACCESS_LEVEL_PUBLIC
But I still cannot get fully qualified class name
UPDATE 2 Here is the full listing of my code:
Project currentProject = DataKeys.PROJECT.getData(e.getDataContext());
PsiClass abstractComponentClass = JavaPsiFacade.getInstance(currentProject).findClass("com.mjolnirr.lib.component.AbstractComponent", GlobalSearchScope.allScope(currentProject));
TreeClassChooser result = TreeClassChooserFactory
.getInstance(currentProject)
.createInheritanceClassChooser("Choose the class to generate manifest",
GlobalSearchScope.projectScope(currentProject),
abstractComponentClass,
false,
false,
null);
result.showDialog();
PsiClass classToGenerate = result.getSelected();
List<ManifestMethod> methods = new ArrayList<ManifestMethod>();
for (PsiMethod method : classToGenerate.getAllMethods()) {
// If this method is inherited from the Object class we don't need it
if (isComponentInitialize(method)) {
continue;
}
List<ManifestParameter> parameters = new ArrayList<ManifestParameter>();
for (PsiParameter param : method.getParameterList().getParameters()) {
parameters.add(new ManifestParameter(param.getType().getCanonicalText().replaceAll("\\<.*?\\>", "")));
}
if (method.getReturnType() != null) {
ManifestMethod manifestMethod = new ManifestMethod(method.getName(),
method.getReturnTypeNoResolve().getInternalCanonicalText().replaceAll("\\<.*?\\>", ""),
parameters);
if (!methods.contains(manifestMethod) && isPublic(method)) {
System.out.println("->" + method.getReturnType().getCanonicalText());
methods.add(manifestMethod);
}
}
}
Solved - my test IDEA instance has wrong Java SDK connected.

Java properties containing dollar delimited variables

I'm storing my app settings in properties file that I use in Ant and in the Java app. Maybe it's not good pratice, but I find it very handy to avoid duplications. The file contains variables such as:
usefulstuff.dir = ${user.home}/usefulstuff
So that other people can run the program on *nix systems, provided that they have the usefulstuff folder in their home directory.
Now, the fascinating thing is that this properties file works fine in Ant (the variable gets resolved to /home/username), while when I load the same file directly in the Java app, I get a string containing ${user.home}/usefulstuff, which is not very useful indeed.
I load the props with this code in Ant:
<loadproperties srcFile="myProps.properties"/>
And in the Java app:
FileInputStream ins = new FileInputStream(propFilePath);
myProps.load(ins);
ins.close();
Am I missing anything? Maybe is there a better way to load properties in a Java app than load()?
I don't think it's particularly "fascinating" that this works in Ant - Ant is deliberately written to do so:
Properties are key-value-pairs where Apache Ant tries to expand ${key} to value at runtime.
and
Ant provides access to all system properties as if they had been defined using a <property> task. For example, ${os.name} expands to the name of the operating system.
If you want the same behaviour, you'll need to implement the same sort of logic. It's possible that you could use the classes from Ant directly, if they do what you want - and if you're happy to ship the relevant binaries (and abide by the licence).
Otherwise, you might want to use a regular expression to find all the matches - or (probably simpler) iterate over all of the system properties and do a simple replacement on them.
As Jon said, it should be straighforward to write the property handling yourself. For eg:
import java.util.*;
public class PropertiesTest
{
public static void main(String[] args)
{
Properties props = new Properties();
props.setProperty("foo", "foo/${os.name}/baz/${os.version}");
props.setProperty("bar", "bar/${user.country}/baz/${user.country}");
System.out.println("BEFORE:");
printProperties(props);
resolveSystemProperties(props);
System.out.println("\n\nAFTER:");
printProperties(props);
}
static void resolveSystemProperties(Properties props)
{
Map<String, String> sysProps = readSystemProperties();
Set<String> sysPropRefs = sysProps.keySet();
Enumeration names = props.propertyNames();
while (names.hasMoreElements())
{
String name = (String) names.nextElement();
String value = props.getProperty(name);
for (String ref : sysPropRefs)
{
if (value.contains(ref))
{
value = value.replace(ref, sysProps.get(ref));
}
}
props.setProperty(name, value);
}
}
static Map<String, String> readSystemProperties()
{
Properties props = System.getProperties();
Map<String, String> propsMap =
new HashMap<String, String>(props.size());
Enumeration names = props.propertyNames();
while (names.hasMoreElements())
{
String name = (String) names.nextElement();
propsMap.put("${" + name + "}", props.getProperty(name));
}
return propsMap;
}
static void printProperties(Properties props)
{
Enumeration names = props.propertyNames();
while (names.hasMoreElements())
{
String name = (String) names.nextElement();
String value = props.getProperty(name);
System.out.println(name + " => " + value);
}
}
}

Categories