I want to find all paths between two vertices. I was able to find it using gremlin path function but it too slow.
Equivalent Gremlin: g.v('12:0').both.both.has('idx', 1L).path
How to convert above gremlin to OrientDB SQL?
In OrientDB 2.1, there is (alas) no way to query for "all paths" using OSQL.
There are proposals for OSQL enhancements to support "all paths" functionality -- see in particular https://github.com/orientechnologies/orientdb/issues/4474 --
but apparently this is for 2.2 or beyond.
In the meantime, note that shortestPath(_) does allow one to specify an edge class, so it can potentially be used to explore alternative paths.
With Java, you could use the following code and the following class
OrientGraph g=new OrientGraph(currentPath);
AllPaths allPath = new AllPaths(g);
List<List<Vertex>> paths=allPath.getPaths("#11:0","#11:7");
Class AllPaths
import java.util.ArrayList;
import java.util.List;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.orient.OrientGraph;
public class AllPaths {
private boolean stop=false;
private Vertex vertexFrom=null;
private List<Vertex> vertexPreviousStep=new ArrayList<Vertex>();
private List<Vertex> vertexCurrently=new ArrayList<Vertex>();
private List<List<Vertex>> paths=new ArrayList<List<Vertex>>();
private OrientGraph g;
public AllPaths(OrientGraph g) {
this.g=g;
}
protected List<List<Vertex>> getPaths(String ridFrom, String ridTo) {
if(!check(ridFrom,ridTo))
return paths;
vertexPreviousStep.add(vertexFrom);
List<Vertex> p=new ArrayList<Vertex>();
p.add(vertexFrom);
paths.add(p);
int step=1;
do{
stop=false;
for(Vertex v: vertexPreviousStep){
List<Vertex> toAdd=new ArrayList<Vertex>();
Iterable<Vertex> nodes = (Iterable<Vertex>) v.getVertices(Direction.OUT);
for(Vertex v1:nodes){
toAdd.add(v1);
if(!v1.getId().toString().equals(ridTo))
vertexCurrently.add(v1);
}
if(toAdd.size()!=0)
setPaths(v,toAdd,step);
}
change();
step++;
}while(stop==true);
return cleanPaths(ridTo);
}
private boolean check(String ridFrom,String ridTo) {
boolean findFrom=false,findTo=false;
for(Vertex v:g.getVertices()){
if(v.getId().toString().equals(ridFrom)){
findFrom=true;
vertexFrom=v;
}
else if(v.getId().toString().equals(ridTo))
findTo=true;
}
if(findFrom==false || findTo==false)
return false;
return true;
}
public void change(){
vertexPreviousStep.clear();
for(Vertex v:vertexCurrently)
vertexPreviousStep.add(v);
vertexCurrently.clear();
}
private void setPaths(Vertex previousVertex,List<Vertex> toAdd,int step) {
for(int i=0;i<paths.size();i++){
List<Vertex> list=paths.get(i);
Vertex last=list.get(list.size()-1);
if(last.getId().toString().equals(previousVertex.getId().toString()) && list.size()==step){
int j=0;
for(Vertex v1:toAdd){
boolean vertexFound=false;
for(Vertex v2:list){
if(v2.getId().toString().equals(v1.getId().toString()))
vertexFound=true;
}
if(vertexFound==false){
List<Vertex> listVertex=new ArrayList<Vertex>();
for(Vertex p:list)
listVertex.add(p);
listVertex.add(v1);
if(j==0){
stop=true;
paths.set(i,listVertex);
j++;
}
else
paths.add(listVertex);
}
}
}
}
}
public List<List<Vertex>> cleanPaths(String ridTo){
for(int i=0;i<paths.size();i++){
List<Vertex> list=paths.get(i);
if(!list.get(list.size()-1).getId().toString().equals(ridTo)){
paths.remove(i);
i--;
}
}
return paths;
}
}
If you want I can write a javascript function
Related
Could someone give me an example of how to extract coordinates for a 'word' with PDFBox
I am using this link to extract positions of individual characters:
https://www.tutorialkart.com/pdfbox/how-to-extract-coordinates-or-position-of-characters-in-pdf/
I am using this link to extract words:
https://www.tutorialkart.com/pdfbox/extract-words-from-pdf-document/
I am stuck getting coordinates for whole words.
You can extract the coordinates of words by collecting all the TextPosition objects building a word and combining their bounding boxes.
Implementing this along the lines of the two tutorials you referenced, you can extend PDFTextStripper like this:
public class GetWordLocationAndSize extends PDFTextStripper {
public GetWordLocationAndSize() throws IOException {
}
#Override
protected void writeString(String string, List<TextPosition> textPositions) throws IOException {
String wordSeparator = getWordSeparator();
List<TextPosition> word = new ArrayList<>();
for (TextPosition text : textPositions) {
String thisChar = text.getUnicode();
if (thisChar != null) {
if (thisChar.length() >= 1) {
if (!thisChar.equals(wordSeparator)) {
word.add(text);
} else if (!word.isEmpty()) {
printWord(word);
word.clear();
}
}
}
}
if (!word.isEmpty()) {
printWord(word);
word.clear();
}
}
void printWord(List<TextPosition> word) {
Rectangle2D boundingBox = null;
StringBuilder builder = new StringBuilder();
for (TextPosition text : word) {
Rectangle2D box = new Rectangle2D.Float(text.getXDirAdj(), text.getYDirAdj(), text.getWidthDirAdj(), text.getHeightDir());
if (boundingBox == null)
boundingBox = box;
else
boundingBox.add(box);
builder.append(text.getUnicode());
}
System.out.println(builder.toString() + " [(X=" + boundingBox.getX() + ",Y=" + boundingBox.getY()
+ ") height=" + boundingBox.getHeight() + " width=" + boundingBox.getWidth() + "]");
}
}
(ExtractWordCoordinates inner class)
and run it like this:
PDDocument document = PDDocument.load(resource);
PDFTextStripper stripper = new GetWordLocationAndSize();
stripper.setSortByPosition( true );
stripper.setStartPage( 0 );
stripper.setEndPage( document.getNumberOfPages() );
Writer dummy = new OutputStreamWriter(new ByteArrayOutputStream());
stripper.writeText(document, dummy);
(ExtractWordCoordinates test testExtractWordsForGoodJuJu)
Applied to the apache.pdf example the tutorials use you get:
2017-8-6 [(X=26.004425048828125,Y=22.00372314453125) height=5.833024024963379 width=36.31868362426758]
Welcome [(X=226.44479370117188,Y=22.00372314453125) height=5.833024024963379 width=36.5999755859375]
to [(X=265.5881652832031,Y=22.00372314453125) height=5.833024024963379 width=8.032623291015625]
The [(X=276.1641845703125,Y=22.00372314453125) height=5.833024024963379 width=14.881439208984375]
Apache [(X=293.5890197753906,Y=22.00372314453125) height=5.833024024963379 width=29.848846435546875]
Software [(X=325.98126220703125,Y=22.00372314453125) height=5.833024024963379 width=35.271636962890625]
Foundation! [(X=363.7962951660156,Y=22.00372314453125) height=5.833024024963379 width=47.871429443359375]
Custom [(X=334.0334777832031,Y=157.6195068359375) height=4.546705722808838 width=25.03936767578125]
Search [(X=360.8929138183594,Y=157.6195068359375) height=4.546705722808838 width=22.702728271484375]
You can create CustomPDFTextStripper which extends PDFTextStripper and override protected void writeString(String text, List<TextPosition> textPositions). In this overriden method you need to split textPositions by the word separator to get List<TextPosition> for each word. After that you can join each character and compute bounding box.
Full example below which contains also drawing of the resulting bounding boxes.
package com.example;
import lombok.Value;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.TextPosition;
import org.junit.Ignore;
import org.junit.Test;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class PdfBoxTest {
private static final String BASE_DIR_PATH = "C:\\Users\\Milan\\50330484";
private static final String INPUT_FILE_PATH = "input.pdf";
private static final String OUTPUT_IMAGE_PATH = "output.jpg";
private static final String OUTPUT_BBOX_IMAGE_PATH = "output-bbox.jpg";
private static final float FROM_72_TO_300_DPI = 300.0f / 72.0f;
#Test
public void run() throws Exception {
pdfToImage();
drawBoundingBoxes();
}
#Ignore
#Test
public void pdfToImage() throws IOException {
PDDocument document = PDDocument.load(new File(BASE_DIR_PATH, INPUT_FILE_PATH));
PDFRenderer renderer = new PDFRenderer(document);
BufferedImage image = renderer.renderImageWithDPI(0, 300);
ImageIO.write(image, "JPEG", new File(BASE_DIR_PATH, OUTPUT_IMAGE_PATH));
}
#Ignore
#Test
public void drawBoundingBoxes() throws IOException {
PDDocument document = PDDocument.load(new File(BASE_DIR_PATH, INPUT_FILE_PATH));
List<WordWithBBox> words = getWords(document);
draw(words);
}
private List<WordWithBBox> getWords(PDDocument document) throws IOException {
CustomPDFTextStripper customPDFTextStripper = new CustomPDFTextStripper();
customPDFTextStripper.setSortByPosition(true);
customPDFTextStripper.setStartPage(0);
customPDFTextStripper.setEndPage(1);
Writer writer = new OutputStreamWriter(new ByteArrayOutputStream());
customPDFTextStripper.writeText(document, writer);
List<WordWithBBox> words = customPDFTextStripper.getWords();
return words;
}
private void draw(List<WordWithBBox> words) throws IOException {
BufferedImage bufferedImage = ImageIO.read(new File(BASE_DIR_PATH, OUTPUT_IMAGE_PATH));
Graphics2D graphics = bufferedImage.createGraphics();
graphics.setColor(Color.GREEN);
List<Rectangle> rectangles = words.stream()
.map(word -> new Rectangle(word.getX(), word.getY(), word.getWidth(), word.getHeight()))
.collect(Collectors.toList());
rectangles.forEach(graphics::draw);
graphics.dispose();
ImageIO.write(bufferedImage, "JPEG", new File(BASE_DIR_PATH, OUTPUT_BBOX_IMAGE_PATH));
}
private class CustomPDFTextStripper extends PDFTextStripper {
private final List<WordWithBBox> words;
public CustomPDFTextStripper() throws IOException {
this.words = new ArrayList<>();
}
public List<WordWithBBox> getWords() {
return new ArrayList<>(words);
}
#Override
protected void writeString(String text, List<TextPosition> textPositions) throws IOException {
String wordSeparator = getWordSeparator();
List<TextPosition> wordTextPositions = new ArrayList<>();
for (TextPosition textPosition : textPositions) {
String str = textPosition.getUnicode();
if (wordSeparator.equals(str)) {
if (!wordTextPositions.isEmpty()) {
this.words.add(createWord(wordTextPositions));
wordTextPositions.clear();
}
} else {
wordTextPositions.add(textPosition);
}
}
super.writeString(text, textPositions);
}
private WordWithBBox createWord(List<TextPosition> wordTextPositions) {
String word = wordTextPositions.stream()
.map(TextPosition::getUnicode)
.collect(Collectors.joining());
int minX = Integer.MAX_VALUE;
int minY = Integer.MAX_VALUE;
int maxX = Integer.MIN_VALUE;
int maxY = Integer.MIN_VALUE;
for (TextPosition wordTextPosition : wordTextPositions) {
minX = Math.min(minX, from72To300Dpi(wordTextPosition.getXDirAdj()));
minY = Math.min(minY, from72To300Dpi(wordTextPosition.getYDirAdj() - wordTextPosition.getHeightDir()));
maxX = Math.max(maxX, from72To300Dpi(wordTextPosition.getXDirAdj() + wordTextPosition.getWidthDirAdj()));
maxY = Math.max(maxY, from72To300Dpi(wordTextPosition.getYDirAdj()));
}
return new WordWithBBox(word, minX, minY, maxX - minX, maxY - minY);
}
}
private int from72To300Dpi(float f) {
return Math.round(f * FROM_72_TO_300_DPI);
}
#Value
private class WordWithBBox {
private final String word;
private final int x;
private final int y;
private final int width;
private final int height;
}
}
Note:
If you are interested in other options, you can check also Poppler
PDF to image
pdftoppm -r 300 -jpeg input.pdf output
Generate an XHTML file containing bounding box information for each word in the file.
pdftotext -r 300 -bbox input.pdf
As you can see, all rules can be listed in project explorer, i am wondering Drools workbench has such a Rest API for this, but I went through online document document, there is no such API. any suggestion on this? thanks in advance.
https://docs.jboss.org/drools/release/latest/drools-docs/html/ch20.html#d0e22619
Best Regards
Yuhua
As far as I know, there is no REST API to do that (public at least). One option do you have though is to use git to get that information from the workbench.
The storage of the workbench is based on git. Each repository in the workbench is actually a git repository. The workbench allows you to clone those repositories and to do whatever you need with them just as with any other git repo out there.
Inside each of the git repositories you will find zero or more maven projects. Indeed, each of the projects you see in the workbench is a real maven project. The different assets in your projects (drl rules, guided rules, decision table, etc.) will be available under the resources directory of the corresponding project.
Hope it helps,
As Esteban Aliverti mentioned, there is no ready to use API to achieve this. However, we can write a custom extension to KIE Server to fetch all the rules deployed.
It is explained in detailed here.
I have similar use case in my application and did the following implementation for fetching rules.
CusomtDroolsKieServerApplicationComponentsService
public class CusomtDroolsKieServerApplicationComponentsService implements KieServerApplicationComponentsService {
private static final String OWNER_EXTENSION = "Drools";
public Collection<Object> getAppComponents(String extension, SupportedTransports type, Object... services) {
// skip calls from other than owning extension
if (!OWNER_EXTENSION.equals(extension)) {
return Collections.emptyList();
}
RulesExecutionService rulesExecutionService = null;
KieServerRegistry context = null;
for (Object object : services) {
if (RulesExecutionService.class.isAssignableFrom(object.getClass())) {
rulesExecutionService = (RulesExecutionService) object;
continue;
} else if (KieServerRegistry.class.isAssignableFrom(object.getClass())) {
context = (KieServerRegistry) object;
continue;
}
}
List<Object> components = new ArrayList<Object>(1);
if (SupportedTransports.REST.equals(type)) {
components.add(new RuleRESTService(rulesExecutionService, context));
}
return components;
}
RuleRestService
#Path("server/containers/instances/{id}/ksession")
public class RuleRESTService {
private RulesExecutionService rulesExecutionService;
private KieServerRegistry registry;
public RuleRESTService() {
}
public RuleRESTService(RulesExecutionService rulesExecutionService, KieServerRegistry registry) {
this.rulesExecutionService = rulesExecutionService;
this.registry = registry;
}
public RulesExecutionService getRulesExecutionService() {
return rulesExecutionService;
}
public void setRulesExecutionService(RulesExecutionService rulesExecutionService) {
this.rulesExecutionService = rulesExecutionService;
}
public KieServerRegistry getRegistry() {
return registry;
}
public void setRegistry(KieServerRegistry registry) {
this.registry = registry;
}
#POST
#Path("/{ksessionId}")
#Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
#Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response fetchAllRules(#Context HttpHeaders headers, #PathParam("id") String id,
#PathParam("ksessionId") String ksessionId, String cmdPayload) {
Variant v = getVariant(headers);
try {
System.out.println("CREATING KieContainerInstance ");
KieContainerInstance kci = registry.getContainer(id);
String contentType = getContentType(headers);
MarshallingFormat format = MarshallingFormat.fromType(contentType);
if (format == null) {
format = MarshallingFormat.valueOf(contentType);
}
Marshaller marshaller = kci.getMarshaller(format);
RuleAccessor accessor = new RuleAccessor();
List<RuleData> rules = accessor.fetchAllRules(kci.getKieContainer());
String result = marshaller.marshall(rules);
return createResponse(result, v, Response.Status.OK);
} catch (Exception ex) {
ex.printStackTrace();
String response = "Execution failed with error : " + ex.getMessage();
System.out.println("Returning Failure response with content '{}' :" + response);
return createResponse(response, v, Response.Status.INTERNAL_SERVER_ERROR);
}
}
RuleAccessor
public class RuleAccessor {
public List<RuleData> fetchAllRules(KieContainer kContainer) {
kContainer.getKieBaseNames().stream()
.forEach(kieBase -> rules.addAll(fetchRules(kContainer1.getKieBase(kieBase))));
return rules;
}
public List<RuleData> fetchRules(KieBase kieBase) {
List<RuleData> ruleData = new ArrayList<>();
for (KiePackage kp : kieBase.getKiePackages()) {
RuleData data = new RuleData();
for (Rule r1 : kp.getRules()) {
RuleImpl r = (RuleImpl) r1;
data.agendaGroup(r.getAgendaGroup()).packageId(r.getPackageName()).ruleName(r.getName())
.enabled(Boolean.getBoolean((((EnabledBoolean) r.getEnabled()).toString())))
.effectiveDate(String.valueOf(r.getDateEffective()))
.dateExpires(String.valueOf(r.getDateExpires())).dialect(r.getDialect())
.salience(r.getSalienceValue()).metaData(r.getMetaData());
try {
Resource resource = r.getResource();
Reader reader = resource.getReader();
BufferedReader bufferedReader = new BufferedReader(reader);
String line = null;
StringBuilder builder = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) {
builder.append(line);
}
data.ruleContent(builder.toString());
ruleData.add(data);
} catch (IOException e) {
e.printStackTrace();
}
}
}
return ruleData;
}
public static class RuleData {
private String packageId;
private String ruleName;
private String type;
private String agendaGroup;
private String ruleContent;
private boolean isEnabled;
private String effectiveDate;
private String dateExpires;
private String dialect;
private int salience;
private Map<String, Object> metaData;
public boolean isEnabled() {
return isEnabled;
}
public RuleData enabled(boolean isEnabled) {
this.isEnabled = isEnabled;
return this;
}
public String effectiveDate() {
return effectiveDate;
}
public RuleData effectiveDate(String effectiveDate) {
this.effectiveDate = effectiveDate;
return this;
}
public String getDateExpires() {
return dateExpires;
}
public RuleData dateExpires(String dateExpires) {
this.dateExpires = dateExpires;
return this;
}
public String getDialect() {
return dialect;
}
public RuleData dialect(String dialect) {
this.dialect = dialect;
return this;
}
public int getSalience() {
return salience;
}
public RuleData salience(int salience) {
this.salience = salience;
return this;
}
public Map<String, Object> getMetaData() {
return metaData;
}
public RuleData metaData(Map<String, Object> metaData) {
this.metaData = metaData;
return this;
}
public String getRuleContent() {
return ruleContent;
}
public RuleData ruleContent(String ruleContent) {
this.ruleContent = ruleContent;
return this;
}
public String getPackageId() {
return packageId;
}
public RuleData packageId(String packageId) {
this.packageId = packageId;
return this;
}
public String getRuleName() {
return ruleName;
}
public RuleData ruleName(String ruleName) {
this.ruleName = ruleName;
return this;
}
public String getType() {
return type;
}
public RuleData type(String type) {
this.type = type;
return this;
}
public String getAgendaGroup() {
return agendaGroup;
}
public RuleData agendaGroup(String agendaGroup) {
this.agendaGroup = agendaGroup;
return this;
}
}
}
You can make a REST call to Kie Server from you application to access all the rules available for the given container.
http://localhost:8080/kie-server/services/rest/server/containers/instances/<container-id>/ksession/<session-id>
I write online game. For game logic, I need select random users(etc) from database. How to achive this with java api? What the most perfomance way to do this?
I can use something like(pseudocode): select from User skip(randomNum(0,usersCount)) limit 1 but how write in documentation - skip has bad performance.
I have tried with this code
int numberRandom= 5;
String string="[";
int cluster= db.getMetadata().getSchema().getClass("User").getClusterIds()[0];
for(int i=0;i<numberRandom;i++){
int random=ThreadLocalRandom.current().nextInt(0, 96000);
if(i==(numberRandom-1))
string += cluster+":"+random + "]";
else
string += cluster+":"+random + ",";
}
Iterable<Vertex> result = g.command(new OCommandSQL("select from "+ string)).execute();
for(Vertex v:result)
System.out.println(v.getId());
Let me know if it can be a good solution for you
I wrote two java classes, both are getting X random users from a specific cluster.
The first one seams faster to me. (about 0.8s vs 1.2s)
testRandom.java
public class testRandom {
public static void main(String[] args) {
// TODO Auto-generated method stub
String nomeDb = "RandomUser";
try {
OServerAdmin serverAdmin = new OServerAdmin("remote:localhost/"+nomeDb).connect("root", "root");
if(serverAdmin.existsDatabase()){ // il db esiste
//connessione a db
OrientGraph g = new OrientGraph("remote:localhost/"+nomeDb);
//------------------------------------------------
long Tbegin,Tend;
float millis;
Tbegin = System.currentTimeMillis();
int numberRandom= 5;
int random;
String cluster = "user";
Iterable<Vertex> vertices = g.command(new OCommandSQL("select from cluster:"+cluster)).execute();
List<Vertex> v_array = new ArrayList<Vertex>();
List<Vertex> res = new ArrayList<Vertex>();
for(Vertex v : vertices){
v_array.add(v);
}
int arraysize = v_array.size();
for(int i=0;i<numberRandom;i++){
random=ThreadLocalRandom.current().nextInt(0, arraysize);
res.add(v_array.get(random));
}
for(Vertex v : res){
System.out.println(v.getId());
}
Tend = System.currentTimeMillis();
millis = (Tend-Tbegin);
System.out.println("--Execution time: "+millis/1000+ "s\n");
//------------------------------------------------
//chiude db
g.shutdown();
}
else{
System.out.println("Il database '"+ nomeDb + "' non esiste");
}
serverAdmin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
testRandomSkip.java
public class testRandom_skip {
public static void main(String[] args) {
// TODO Auto-generated method stub
String nomeDb = "RandomUser";
try {
OServerAdmin serverAdmin = new OServerAdmin("remote:localhost/"+nomeDb).connect("root", "root");
if(serverAdmin.existsDatabase()){ // il db esiste
//connessione a db
OrientGraph g = new OrientGraph("remote:localhost/"+nomeDb);
//------------------------------------------------
long Tbegin,Tend;
float millis;
Tbegin = System.currentTimeMillis();
int numberRandom= 5;
int random;
String cluster = "user";
List<Vertex> res = new ArrayList<Vertex>();
Iterable<Vertex> q_count_V = g.command(new OCommandSQL("select count(*) from cluster:"+cluster)).execute();
Long count_V = 0l;
for(Vertex v : q_count_V){
count_V=v.getProperty("count");
break;
}
for(int i=0;i<numberRandom;i++){
random=(int)ThreadLocalRandom.current().nextLong(0, count_V);
Iterable<Vertex> vertex = g.command(new OCommandSQL("select from cluster:"+cluster+" skip "+random+" limit 1")).execute();
for(Vertex v : vertex){
res.add(v);
break;
}
}
for(Vertex v : res){
System.out.println(v.getId());
}
Tend = System.currentTimeMillis();
millis = (Tend-Tbegin);
System.out.println("--Execution time: "+millis/1000+ "s\n");
//------------------------------------------------
//chiude db
g.shutdown();
}
else{
System.out.println("Il database '"+ nomeDb + "' non esiste");
}
serverAdmin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Hope it helps.
Ivan
I have a simple scenario,
I want to select all the path between Adrian and Permies,
The shortestPath function gives me
Adrian -> Permies
but I cannot get the other path which is,
Adrian -> Devs -> Permies
With Java, you could use the following code and the following class
OrientGraph g=new OrientGraph(currentPath);
AllPaths allPath = new AllPaths(g);
List<List<Vertex>> paths=allPath.getPaths("#11:0","#11:7");
Class AllPaths
import java.util.ArrayList;
import java.util.List;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.orient.OrientGraph;
public class AllPaths {
private boolean stop=false;
private Vertex vertexFrom=null;
private List<Vertex> vertexPreviousStep=new ArrayList<Vertex>();
private List<Vertex> vertexCurrently=new ArrayList<Vertex>();
private List<List<Vertex>> paths=new ArrayList<List<Vertex>>();
private OrientGraph g;
public AllPaths(OrientGraph g) {
this.g=g;
}
protected List<List<Vertex>> getPaths(String ridFrom, String ridTo) {
if(!check(ridFrom,ridTo))
return paths;
vertexPreviousStep.add(vertexFrom);
List<Vertex> p=new ArrayList<Vertex>();
p.add(vertexFrom);
paths.add(p);
int step=1;
do{
stop=false;
for(Vertex v: vertexPreviousStep){
List<Vertex> toAdd=new ArrayList<Vertex>();
Iterable<Vertex> nodes = (Iterable<Vertex>) v.getVertices(Direction.OUT);
for(Vertex v1:nodes){
toAdd.add(v1);
if(!v1.getId().toString().equals(ridTo))
vertexCurrently.add(v1);
}
if(toAdd.size()!=0)
setPaths(v,toAdd,step);
}
change();
step++;
}while(stop==true);
return cleanPaths(ridTo);
}
private boolean check(String ridFrom,String ridTo) {
boolean findFrom=false,findTo=false;
for(Vertex v:g.getVertices()){
if(v.getId().toString().equals(ridFrom)){
findFrom=true;
vertexFrom=v;
}
else if(v.getId().toString().equals(ridTo))
findTo=true;
}
if(findFrom==false || findTo==false)
return false;
return true;
}
public void change(){
vertexPreviousStep.clear();
for(Vertex v:vertexCurrently)
vertexPreviousStep.add(v);
vertexCurrently.clear();
}
private void setPaths(Vertex previousVertex,List<Vertex> toAdd,int step) {
for(int i=0;i<paths.size();i++){
List<Vertex> list=paths.get(i);
Vertex last=list.get(list.size()-1);
if(last.getId().toString().equals(previousVertex.getId().toString()) && list.size()==step){
int j=0;
for(Vertex v1:toAdd){
boolean vertexFound=false;
for(Vertex v2:list){
if(v2.getId().toString().equals(v1.getId().toString()))
vertexFound=true;
}
if(vertexFound==false){
List<Vertex> listVertex=new ArrayList<Vertex>();
for(Vertex p:list)
listVertex.add(p);
listVertex.add(v1);
if(j==0){
stop=true;
paths.set(i,listVertex);
j++;
}
else
paths.add(listVertex);
}
}
}
}
}
public List<List<Vertex>> cleanPaths(String ridTo){
for(int i=0;i<paths.size();i++){
List<Vertex> list=paths.get(i);
if(!list.get(list.size()-1).getId().toString().equals(ridTo)){
paths.remove(i);
i--;
}
}
return paths;
}
}
Well, I gonna share 2 ways:
a) using traverse but specifying the deep:
TRAVERSE * FROM (SELECT FROM Source WHERE field = 'value') MAXDEPTH 3
b) using some constraint clause:
SELECT FROM (TRAVERSE * FROM (SELECT FROM Source WHERE field = 'value') while #rid <> (SELECT FROM Target WHERE field='value'))
I'm experiencing a problem when D&D a custom object from Swing to JavaFX and I'm wondering if I'm doing something wrong or its probably a Java FX bug.
My Transferable has been defined as the following:
public class TransferableEmployee implements Transferable {
public static final DataFlavor EMPLOYEE_FLAVOR = new DataFlavor(Employee[].class, "Employee");
public static final DataFlavor DEFINITION_FLAVOR = new DataFlavor(PropertyDefinition[].class, "Definition");
private static final DataFlavor FFLAVORS [] = {EMPLOYEE_FLAVOR, DEFINITION_FLAVOR};
private Employee[] employees;
private PropertyDefinition[] propertyDefinitions;
public MintTransferableEmployee(Employee[] employees, PropertyDefinition[] propertyDefinitions) {
this.employees = employees != null ? employees.clone() : null;
this.propertyDefinitions = propertyDefinitions != null ? propertyDefinitions.clone() : null;
}
public DataFlavor[] getTransferDataFlavors() {
return FFLAVORS.clone();
}
public Object getTransferData(DataFlavor aFlavor) throws UnsupportedFlavorException {
Object returnObject = null;
if (aFlavor.equals(EMPLOYEE_FLAVOR)) {
returnObject = employees;
}
else if(aFlavor.equals(DEFINITION_FLAVOR)){
returnObject = propertyDefinitions;
}
else{
throw new UnsupportedFlavorException(aFlavor);
}
return returnObject;
}
public boolean isDataFlavorSupported(DataFlavor aFlavor) {
boolean lReturnValue = false;
for (int i=0, n=FFLAVORS.length; i<n; i++) {
if (aFlavor.equals(FFLAVORS[i])) {
lReturnValue = true;
break;
}
}
return lReturnValue;
}
}
I've created an imageView (FX Component) where I added the setOnDragOver just as the following:
employeePhotoImageView.setOnDragOver(new EventHandler<DragEvent>() {
#Override
public void handle(DragEvent event) {
System.out.println("dragOver");
event.getDragboard().getContentTypes();
event.getDragboard().getContent(DataFormat.lookupMimeType("application/x-java-serialized-object"));
}
});
The getContentTypes() returns a Map with [[application/x-java-serialized-object]], so now I try to get the Content, and this only returns the List of PropertyDefinition but no Employee at all (which in this case, is the one I need).
If I remove the data of the PropertyDefinition in the transferable, the employee is returned in the getContent(DataFormat) method.
For me, this means that JavaFX only works with 1 DataFlavor or somehow it is only returning the last flavor found in the Transferable.
Any clues on this?
Thanks in advanced...