Make prettyPrintTG available via SCL from Simantics/DB-module 98/598/3
authorjsimomaa <jani.simomaa@gmail.com>
Mon, 5 Jun 2017 12:00:05 +0000 (15:00 +0300)
committerJani Simomaa <jani.simomaa@semantum.fi>
Mon, 5 Jun 2017 17:52:54 +0000 (20:52 +0300)
refs #7276

Change-Id: I640f4cb6d929482577ed8874e6b8fadcaa05ba64

bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Layer0Utils.java
bundles/org.simantics.graph/src/org/simantics/graph/refactoring/GraphRefactoringUtils.java
bundles/org.simantics.graph/src/org/simantics/graph/representation/PrettyPrintTG.java
bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphUtils.java
bundles/org.simantics.scl.db/scl/Simantics/DB.scl

index adc51c16d88ef0f74f1f849f421e9156398c69f1..08dd63ce0e25c4bf11084bc8402eb802cd51a49d 100644 (file)
@@ -106,6 +106,7 @@ import org.simantics.graph.db.TransferableGraphs;
 import org.simantics.graph.diff.Diff;
 import org.simantics.graph.diff.TransferableGraphDelta1;
 import org.simantics.graph.refactoring.GraphRefactoringUtils;
+import org.simantics.graph.representation.PrettyPrintTG;
 import org.simantics.graph.representation.TransferableGraph1;
 import org.simantics.layer0.Layer0;
 import org.simantics.operation.Layer0X;
@@ -1193,7 +1194,7 @@ public class Layer0Utils {
 
     }
 
-    private static TransferableGraphSource makeTGSource(ReadGraph graph, Resource r) throws DatabaseException {
+    public static TransferableGraphSource makeTGSource(ReadGraph graph, Resource r) throws DatabaseException {
 
        SimanticsClipboardImpl cp = new SimanticsClipboardImpl();
        CopyHandler c1 = graph.adapt(r, CopyHandler.class);
@@ -1378,4 +1379,11 @@ public class Layer0Utils {
        
     }
 
+    public static String prettyPrintResource(ReadGraph graph, Resource resource) throws Exception {
+        TransferableGraphSource source = makeTGSource(graph, resource);
+        TransferableGraph1 tg = TransferableGraphs.create(graph, source);
+        GraphRefactoringUtils.fixOntologyExport(tg);
+        return PrettyPrintTG.print(tg);
+    }
+
 }
index 9f8eca398f139c10a5a18801522230427fa29f08..90b134e33762b5f991baa5288a2974906f2bad7b 100644 (file)
@@ -128,6 +128,22 @@ public class GraphRefactoringUtils {
                                
                        return;
                        
+                } else if (ext.type.startsWith("http://")) {
+                    String first = "http://Projects/Development Project";
+                    Identity path = recursePath(tg, first);
+                    id.definition = new Internal(path.resource, ext.name);
+                    
+                    GraphStore store = TransferableGraphConversion.convert(tg);
+                    int rootId = store.identities.createPathToId(UriUtils.uriToPath(first + "/" + ext.name));
+                    propagateNewMarks(store.identities, rootId);
+
+                    TransferableGraph1 tgNew = TransferableGraphConversion.convert(store);
+                        
+                    tg.resourceCount = tgNew.resourceCount;
+                    tg.identities = tgNew.identities;
+                    tg.values = tgNew.values;
+                    tg.statements = tgNew.statements;
+
                 }
             }
         }
index 00d17100ec461bb5800a63e93e1b40175d90a204..bb776d5df649eaa08ac455942e453718c9d2a721 100644 (file)
@@ -11,6 +11,7 @@ import java.nio.file.Paths;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
@@ -19,22 +20,29 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.simantics.databoard.Bindings;
-import org.simantics.databoard.Datatypes;
 import org.simantics.databoard.binding.Binding;
 import org.simantics.databoard.binding.mutable.Variant;
 import org.simantics.databoard.container.DataContainers;
-import org.simantics.databoard.type.Datatype;
+import org.simantics.databoard.parser.DataValuePrinter;
+import org.simantics.databoard.parser.PrintFormat;
+import org.simantics.databoard.parser.repository.DataValueRepository;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import gnu.trove.list.array.TIntArrayList;
+import gnu.trove.map.hash.TIntIntHashMap;
 import gnu.trove.map.hash.TIntObjectHashMap;
+import gnu.trove.procedure.TIntIntProcedure;
 import gnu.trove.set.hash.TLongHashSet;
 
 /**
  * @author Antti Villberg
  * @since 1.24.0
  */
-public class PrettyPrintTG extends TransferableGraphUtils {
+public class PrettyPrintTG {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(PrettyPrintTG.class);
+    
        int blankCounter = 0;
        MessageDigest m;
 
@@ -50,16 +58,33 @@ public class PrettyPrintTG extends TransferableGraphUtils {
                final int resource;
                boolean newResource = false;
                
+               int parent;
+               
+               boolean inlined = false;
+               
                // -1 = no owner, -2 = multiple owners
-               int owner = -1;
-               int ownerPredicate = 0;
+               
+               // Set<ResourceInfo> ownedBy
+               Set<ResourceInfo> ownedBy = new HashSet<>();
+               
+               // A Map<Integer, Integer> containing information about resource that this resource owns and what are the predicates for forming this ownership
+               TIntIntHashMap ownedResourcesWithPredicates = new TIntIntHashMap();
+               
+//             int owner = -1;
+//             int ownerPredicate = 0;
                String aliasURI = null;
                TIntArrayList owned = new TIntArrayList();
                //TIntObjectHashMap<TIntHashSet> statements = new TIntObjectHashMap<TIntHashSet>();
-               public ResourceInfo(boolean hasURI, String name, int resource) {
+               public ResourceInfo(boolean hasURI, String name, int resource, int parent) {
                        this.hasURI = hasURI;
                        this.name = name;
                        this.resource = resource;
+                       this.parent = parent;
+               }
+               
+               @Override
+               public String toString() {
+                   return name + (aliasURI != null ? " = <" + aliasURI + ">" : "");
                }
        }
 
@@ -79,32 +104,32 @@ public class PrettyPrintTG extends TransferableGraphUtils {
                else return name;
        }
 
-       ResourceInfo recurseURI(TransferableGraph1 graph, Identity parent, String parentName) {
-               String name = parentName + "." + tgNodeName(getName(parent));
-               ResourceInfo info = new ResourceInfo(true, name, parent.resource); 
+       ResourceInfo recurseURI(TransferableGraph1 graph, Identity parent, String parentName, int parentId) {
+               String name = parentName + "." + tgNodeName(TransferableGraphUtils.getName(parent));
+               ResourceInfo info = new ResourceInfo(true, name, parent.resource, parentId); 
                infos.put(parent.resource, info);
-               for(Identity child : getChildren(graph, parent)) {
-                       recurseURI(graph, child, name);
+               for(Identity child : TransferableGraphUtils.getChildren(graph, parent)) {
+                       recurseURI(graph, child, name, info.resource);
                }
                return info;
        }
 
        void discoverBlank(TransferableGraph1 graph, int resource, TIntArrayList todo) throws Exception {
-               TIntArrayList statements = getStatements(graph, resource);
+               TIntArrayList statements = TransferableGraphUtils.getStatements(graph, resource);
                for(int i=0;i<statements.size();i+=2) {
                        int object = statements.get(i+1);
-                       Identity objectId = getIdentity(graph, object);
+                       Identity objectId = TransferableGraphUtils.getIdentity(graph, object);
                        if(objectId != null) {
                                if(objectId.definition instanceof External) continue;
                        }
                        Value value = TransferableGraphUtils.findValue(graph, object);
                        if(value != null) {
-                               infos.put(object, new ResourceInfo(false, printValue(value), object));
+                               infos.put(object, new ResourceInfo(false, printValue(value), object, resource));
                                continue;
                        }
                        ResourceInfo existing = infos.get(object);
                        if(existing == null) {
-                               existing = new ResourceInfo(false, "blank" + blankCounter++, object);
+                               existing = new ResourceInfo(false, "blank" + blankCounter++, object, resource);
                                infos.put(object, existing);
                                todo.add(object);
                        }
@@ -112,52 +137,99 @@ public class PrettyPrintTG extends TransferableGraphUtils {
        }
 
        void discoverOwners(TransferableGraph1 graph, ResourceInfo info) {
+           if (LOGGER.isDebugEnabled())
+               LOGGER.debug("Discovering owners for " + info);
                int resource = info.resource;
-               TIntArrayList statements = getStatements(graph, resource);
+               TIntArrayList statements = TransferableGraphUtils.getStatements(graph, resource);
                for(int i=0;i<statements.size();i+=2) {
                        int predicate = statements.get(i);
                        int object = statements.get(i+1);
                        ResourceInfo existing = infos.get(object);
-                       if(existing == null) continue;
-                       if(existing.owner == -1) {
-                               existing.owner = resource;
-                               existing.ownerPredicate = predicate;
-                               //System.err.println("First owner " + info.name + " => " + predicateURI + " " + existing.name);
-                       } else {
-                               existing.owner = -2;
-                               //System.err.println("Multiple owners " + info.name + " => " + predicateURI + " " + existing.name);
+                       if(existing != null) {
+                // Add all owners here for now and resolve the best owner later
+                existing.ownedResourcesWithPredicates.put(resource, predicate);
+                           // Check if predicate is inverse, this just resolves all predicates to be inverse with ending "Inverse"..
+                           String predicateUri = rewritePredicateURI(graph, predicate);
+                           if (!predicateUri.endsWith("Inverse")) {
+                               existing.ownedBy.add(info);
+                            if (LOGGER.isDebugEnabled()) {
+                                   LOGGER.debug("    " + existing + " owns " + info + " with " + predicateUri);
+                            }
+                           }
                        }
                }
-               
        }
 
-       String printValue(Value value) throws Exception {
-               Variant variant = value.value;
-               Datatype dt = variant.getBinding().type();
-               if(Datatypes.STRING.equals(dt)) {
-                       String s = (String)variant.getValue(Bindings.STRING);
-                       if(s.contains("\n")) {
-                               return "\"\"\"" + s + "\"\"\"";
-                       } else {
-                               return "\"" + s + "\"";         
-                       }
-               } else if(Datatypes.BOOLEAN.equals(dt)) {
-                       Boolean i = (Boolean)variant.getValue(Bindings.BOOLEAN);
-                       return i ? "true" : "false";
-               } else if(Datatypes.INTEGER.equals(dt)) {
-                       Integer i = (Integer)variant.getValue(Bindings.INTEGER);
-                       return i.toString();
-               } else if(Datatypes.LONG.equals(dt)) {
-                       Long i = (Long)variant.getValue(Bindings.LONG);
-                       return i.toString();
-               } else {
-                       byte[] data = variant.getBinding().serializer().serialize(variant.getValue());
-                       m.reset();
-                       m.update(data, 0, data.length);
-                       return "\"" + new BigInteger(1, m.digest()).toString(16) + "\"";
-               }
-
-       }
+    DataValueRepository repo = new DataValueRepository();
+    DataValuePrinter printer = new DataValuePrinter(null, repo);
+       
+    String printValue(Value value) throws Exception {
+        StringBuilder sb = new StringBuilder();
+        printer.setFormat(PrintFormat.SINGLE_LINE);
+        printer.setOutput(sb);
+        
+        Variant variant = value.value;
+        printer.print(variant.getBinding(), variant.getValue());
+        String formattedOutput = sb.toString();
+        if (formattedOutput.length() > 100) {
+            // Ok, value too long, lets calculate a hash for it and store first 100 chars as comment
+              byte[] data = Bindings.getSerializerUnchecked(variant.getBinding()).serialize(variant.getValue());
+              m.reset();
+              m.update(data, 0, data.length);
+              String hash = "\"" + new BigInteger(1, m.digest()).toString(16) + "\"";
+              return hash + " // " + formattedOutput.substring(0, 100) + "..";
+        } else {
+            return formattedOutput;
+        }
+//        
+//        Variant variant = value.value;
+//        Datatype dt = variant.getBinding().type();
+//        if (Datatypes.STRING.equals(dt)) {
+//            String s = (String) variant.getValue(Bindings.STRING);
+//            if (s.contains("\n")) {
+//                return "\"\"\"" + s + "\"\"\"";
+//            } else {
+//                return "\"" + s + "\"";
+//            }
+//        } else if (Datatypes.BOOLEAN.equals(dt)) {
+//            Boolean i = (Boolean) variant.getValue(Bindings.BOOLEAN);
+//            return i ? "true" : "false";
+//        } else if (Datatypes.INTEGER.equals(dt)) {
+//            Integer i = (Integer) variant.getValue(Bindings.INTEGER);
+//            return i.toString();
+//        } else if (Datatypes.LONG.equals(dt)) {
+//            Long i = (Long) variant.getValue(Bindings.LONG);
+//            return i.toString();
+//        } else if (Datatypes.DOUBLE.equals(dt)) {
+//            Double d = (Double) variant.getValue();
+//            return d.toString();
+//        } else if (Datatypes.FLOAT.equals(dt)) {
+//            Float f = (Float) variant.getValue();
+//            return f.toString();
+//        } else if (Datatypes.STRING_ARRAY.equals(dt)) {
+//            return Arrays.toString((String []) variant.getValue());
+//        } else if (Datatypes.BOOLEAN_ARRAY.equals(dt)) {
+//            return Arrays.toString((boolean []) variant.getValue());
+//        } else if (Datatypes.INTEGER_ARRAY.equals(dt)) {
+//            return Arrays.toString((int []) variant.getValue());
+//        } else if (Datatypes.LONG_ARRAY.equals(dt)) {
+//            return Arrays.toString((long []) variant.getValue());
+//        } else if (Datatypes.DOUBLE_ARRAY.equals(dt)) {
+//            return Arrays.toString((double []) variant.getValue());
+//        } else if (Datatypes.FLOAT_ARRAY.equals(dt)) {
+//            return Arrays.toString((float []) variant.getValue());
+//        } else if (Datatypes.BYTE_ARRAY.equals(dt)) {
+//            return Arrays.toString((byte []) variant.getValue());
+////        } else if (dt instanceof ArrayType) {
+////            return Arrays.toString((Object []) variant.getValue());
+//        } else {
+//            byte[] data = Bindings.getSerializerUnchecked(variant.getBinding()).serialize(variant.getValue());
+//            m.reset();
+//            m.update(data, 0, data.length);
+//            return "\"" + new BigInteger(1, m.digest()).toString(16) + "\"";
+//        }
+
+    }
 
        //      void fixInstanceOf(TransferableGraph1 graph, ResourceInfo info) {
        //              Identity id = getIdentity(graph, info.resource);
@@ -176,7 +248,7 @@ public class PrettyPrintTG extends TransferableGraphUtils {
                int parentId = ext.parent;
                //if(parentId == 0) return ext.name;
                //              else {
-               Identity id = getIdentity(tg, parentId);
+               Identity id = TransferableGraphUtils.getIdentity(tg, parentId);
                if(id.definition instanceof External) {
                        return getExternalURI(tg, (External)id.definition) + "/" + name;
                } else if(id.definition instanceof Root) {
@@ -189,7 +261,7 @@ public class PrettyPrintTG extends TransferableGraphUtils {
        }
 
        public static String getExternalURI(TransferableGraph1 tg, int resource) {
-               Identity id = getIdentity(tg, resource);
+               Identity id = TransferableGraphUtils.getIdentity(tg, resource);
                if(id == null) return null;
                if(id.definition instanceof External) {
                        External ext = (External)id.definition;
@@ -221,27 +293,56 @@ public class PrettyPrintTG extends TransferableGraphUtils {
                
        }
 
-       void indent(int indent) {
-               for(int i=0;i<indent;i++) output.append("  ");
+       static void indent(StringBuilder output, int indent) {
+               for(int i=0;i<indent;i++)
+                   output.append("  ");
        }
        
-       void printBlank(TransferableGraph1 graph, String predicateURI2, ResourceInfo info, int indent) {
+       String printBlank(TransferableGraph1 graph, String predicateURI2, ResourceInfo info, int indent) {
 
-               if(info.hasURI) return;
-               indent(indent);
+               if(info.hasURI)
+                   return null;
+               
+               StringBuilder output = new StringBuilder();
+               indent(output, indent);
                output.append(predicateURI2 + " " + info.name + "\n");
 
-               if(info.owner < 0) {
-                       printURI(graph, info, false, indent);
+               if (info.ownedResourcesWithPredicates.isEmpty()) {
+                   String uri = printURI(graph, info, false, indent, false);
+                   if (uri != null)
+                       output.append(uri);
                }
-               
+//             if(info.owner < 0) {
+//                     printURI(graph, info, false, indent);
+//             }
+               return output.toString();
        }
 
-       long longStm(int predicate, int object) {
+       static long longStm(int predicate, int object) {
                return (predicate<<32) | (object & 0xffffffffL); 
        }
 
+
+    private void addInlineStatement(TransferableGraph1 graph, Map<String, Set<String>> statements, String predicate, ResourceInfo objectInfo, int indent) {
+        Set<String> objects = statements.get(predicate);
+        if(objects == null) {
+            objects = new TreeSet<>();
+            statements.put(predicate, objects);
+        }
+        String uri = printURI(graph, objectInfo, false, indent + 1, true);
+        if (uri != null) {
+            // TODO: this is not the right place to remove trailing newline
+            uri = uri.endsWith("\n") ? uri.substring(0, uri.length() - 2) : uri;
+            objects.add(uri);
+        }
+        objectInfo.inlined = true;
+    }
+
+       
        void addStatement(Map<String,Set<String>> statements, String predicate, String object) {
+           // TODO: fix this
+           if (predicate.endsWith("Inverse"))
+               return;
                Set<String> objects = statements.get(predicate);
                if(objects == null) {
                        objects = new TreeSet<>();
@@ -250,19 +351,24 @@ public class PrettyPrintTG extends TransferableGraphUtils {
                objects.add(object);
        }
 
-       void printURI(TransferableGraph1 graph, ResourceInfo info, boolean requireURI, int indent) {
+       String printURI(TransferableGraph1 graph, ResourceInfo info, boolean requireURI, int indent, boolean inline) {
 
-               if(requireURI && !info.hasURI) return;
+               if(requireURI && !info.hasURI)
+                   return null;
+               
+               // Check if this ResourceInfo is already inlined with some other ResourceInfo 
+               if (info.inlined) 
+                   return null;
 
                Map<String,Set<String>> statements = new TreeMap<>();
-               Identity consistsOf = findExternal(graph, "http://www.simantics.org/Layer0-1.1/ConsistsOf");
+               Identity consistsOf = TransferableGraphUtils.findExternal(graph, "http://www.simantics.org/Layer0-1.1/ConsistsOf");
                TLongHashSet processed = new TLongHashSet();
                for(int i=0;i<info.owned.size();i+=2) {
                        long stmId = longStm(info.owned.get(i), info.owned.get(i+1));
                        processed.add(stmId);
                }
                
-               TIntArrayList rawStatements = getStatements(graph, info.resource);
+               TIntArrayList rawStatements = TransferableGraphUtils.getStatements(graph, info.resource);
                for(int i=0;i<rawStatements.size();i+=2) {
                        long stmId = longStm(rawStatements.get(i), rawStatements.get(i+1));
                        if(!processed.add(stmId)) continue;
@@ -272,18 +378,38 @@ public class PrettyPrintTG extends TransferableGraphUtils {
                        if(objectInfo == null) {
                                String objectURI = rewritePredicateURI(graph, rawStatements.get(i+1));
                                addStatement(statements, predicateURI, objectURI);
+                       } else if (objectInfo.ownedBy.size() == 1 && objectInfo.ownedBy.contains(info)) {
+                           // inline printing with _
+                           addInlineStatement(graph, statements, predicateURI, objectInfo, indent);
                        } else {
                                addStatement(statements, predicateURI, objectInfo.name);
                        }
                }
 
-               if(indent == 0) {
+               HashSet<ResourceInfo> debug = new HashSet<>();
+               info.ownedResourcesWithPredicates.forEachEntry(new TIntIntProcedure() {
+            
+            @Override
+            public boolean execute(int owner, int predicate) {
+                ResourceInfo ownerInfo = infos.get(owner);
+                debug.add(ownerInfo);
+//                ResourceInfo predicateInfo = infos.get(predicate);
+//                debug.add(predicateInfo);
+                return true;
+            }
+        });
+
+               StringBuilder output = new StringBuilder();
+               
+               if(indent == 0 || inline) {
                        if("ROOT".equals(info.name)) {
                                output.append("ROOT=<http:/>");
                        } else if (info.aliasURI != null) {
                                output.append(info.name + " = <" + info.aliasURI + ">");
                        } else {
-                               output.append(info.name);
+                           if (inline)
+                               System.out.println("asdasd");
+                               output.append(inline ? "_" : info.name);
                        }
                        Set<String> instanceOfs = statements.get("L0.InstanceOf");
                        if(instanceOfs != null) {
@@ -316,14 +442,13 @@ public class PrettyPrintTG extends TransferableGraphUtils {
                        if("L0.Inherits".equals(predicate)) continue;
                        if("L0.PartOf".equals(predicate)) continue;
                        Set<String> objects = entry.getValue();
+                       indent(output, indent+1);
                        if(objects.size() == 1) {
-                               indent(indent+1);
                                output.append(predicate + " " + objects.iterator().next() + "\n");      
                        } else{
-                               indent(indent+1);
                                output.append(predicate + "\n");        
                                for(String object : objects) {
-                                       indent(indent+1);
+                                       indent(output, indent+1);
                                        output.append("  " + object + "\n");    
                                }
                        }
@@ -332,12 +457,15 @@ public class PrettyPrintTG extends TransferableGraphUtils {
                for(int i=0;i<info.owned.size();i+=2) {
                        String predicateURI = rewritePredicateURI(graph, info.owned.get(i));
                        ResourceInfo ownedInfo = infos.get(info.owned.get(i+1));
-                       printBlank(graph, predicateURI, ownedInfo, indent+1);
+                       String blank = printBlank(graph, predicateURI, ownedInfo, indent+1);
+                       if (blank != null)
+                           output.append(blank);
                }
                
+               return output.toString();
        }
 
-       void prettyPrint(Path input, Path output) throws Exception {
+    void prettyPrint(Path input, Path output) throws Exception {
 
                System.out.format("Converting exported shared ontology%n\t" + input.toString() + "%nto bundle-compatible ontology%n\t" + output.toString());
                try (InputStream is = new BufferedInputStream(Files.newInputStream(input), 128*1024)) {
@@ -376,54 +504,73 @@ public class PrettyPrintTG extends TransferableGraphUtils {
        
        void prettyPrint(TransferableGraph1 graph) throws Exception {
 
+           if (LOGGER.isDebugEnabled())
+               LOGGER.debug("Starting prettyPrint for TransferableGraph with " + graph.resourceCount + " resources, " + graph.identities + " identities, " + graph.statements.length + " statements and " + graph.values.length + " values");
+           
                for(Identity id : graph.identities) {
                        if(id.definition instanceof Internal) {
                                Internal internal = (Internal)id.definition;
                                Identity parent = TransferableGraphUtils.getIdentity(graph, internal.parent);
                                if(parent.definition instanceof External) {
+                       if (LOGGER.isDebugEnabled())
+                           LOGGER.debug("Resolving internal identity " + id);
                                        String name = "BASE";
-                                       ResourceInfo info = new ResourceInfo(true, name, id.resource);
+                                       ResourceInfo info = new ResourceInfo(true, name, id.resource, -1);
                                        info.aliasURI = TransferableGraphUtils.getURI(graph, id.resource);
                                        info.newResource = true;
                                        infos.put(id.resource, info);
-                                       for(Identity child : getChildren(graph, id)) {
-                                               recurseURI(graph, child, name);
+                    if (LOGGER.isDebugEnabled())
+                        LOGGER.debug("    which parent is external " + parent + " and has an aliasURI " + info.aliasURI) ;
+                                       for(Identity child : TransferableGraphUtils.getChildren(graph, id)) {
+                                               recurseURI(graph, child, name, info.resource);
                                        }
+                                       if (LOGGER.isDebugEnabled())
+                                           LOGGER.debug("    and has " + (infos.size() - 1) + " children");
                                }
                        } else if (id.definition instanceof External) {
                                External ext = (External)id.definition;
                                // Try to detect shared libraries
                                if(ext.name.contains("@")) {
-                                       
+                                   
+                                   if (LOGGER.isDebugEnabled())
+                                       LOGGER.debug("Detected an external shared library " + ext);
+                                   
                                        int index = ext.name.indexOf('@');
                                        String prefix = ext.name.substring(0, index);
                                        int index2 = ext.name.indexOf('/', index);
                                        String ontology = index2 == -1 ? ext.name : ext.name.substring(0, index2);  
                                        String uri = TransferableGraphUtils.getURI(graph, id.resource);
+                                       
+                                       if (LOGGER.isDebugEnabled())
+                                           LOGGER.debug("    which was resolved as URI=" + uri + " and prefix " + prefix);
+                                       
                                        ontologies.put(uri, prefix);
                                        
                                } else if (ext.name.contains("-")) {
-
+                                   if (LOGGER.isDebugEnabled())
+                                       LOGGER.debug("Resolving possible ontology " + ext);
                                        String uri = TransferableGraphUtils.getURI(graph, id.resource);
                                Matcher m = versionExtractPattern.matcher(uri);
                                if (m.matches()) {
                                        if(!ontologies.containsKey(uri)) {
                                                        int index = ext.name.indexOf('-');
-                                                       String prefix = ext.name.substring(0, index);
-                                                       ontologies.put(uri, prefix);
+                            String prefix = ext.name.substring(0, index);
+                            if (LOGGER.isDebugEnabled())
+                                LOGGER.debug("    and it was resolved as URI=" + uri + " and prefix " + prefix);
+                            ontologies.put(uri, prefix);
                                        }
                                }
-
                                }
-                               
-
-                               
                        }
                }
                // Discover other resources
+               if (LOGGER.isDebugEnabled())
+                   LOGGER.debug("Discovering other resources..");
+               
                TIntArrayList todo = new TIntArrayList();
                for(ResourceInfo info : infos.valueCollection())
                        todo.add(info.resource);
+               
                while(!todo.isEmpty()) {
                        int resource = todo.removeAt(todo.size()-1);
                        discoverBlank(graph, resource, todo);
@@ -432,34 +579,74 @@ public class PrettyPrintTG extends TransferableGraphUtils {
                        discoverOwners(graph, info);
                //                      for(ResourceInfo info : infos.valueCollection())
                //                              fixInstanceOf(graph, info);
-               for(ResourceInfo info : infos.valueCollection())
-                       if(info.owner >= 0) {
-                               ResourceInfo ownerInfo = infos.get(info.owner);
-                               ownerInfo.owned.add(info.ownerPredicate);
-                               ownerInfo.owned.add(info.resource);
-                       }
-
+               
+        for (ResourceInfo info : infos.valueCollection()) {
+//          Old implementation
+//            if (info.owner >= 0) {
+//                ResourceInfo ownerInfo = infos.get(info.owner);
+//                System.out.println("originalOwner : " + info.owner + " originalPredicate: " + info.ownerPredicate);
+//                ownerInfo.owned.add(info.ownerPredicate);
+//                ownerInfo.owned.add(info.resource);
+//            }
+            
+            if (!info.ownedResourcesWithPredicates.isEmpty() && info.ownedResourcesWithPredicates.size() == 1) {
+                info.ownedResourcesWithPredicates.forEachEntry(new TIntIntProcedure() {
+                    
+                    @Override
+                    public boolean execute(int owner, int predicate) {
+                        ResourceInfo ownerInfo = infos.get(owner);
+                        ownerInfo.owned.add(predicate);
+                        ownerInfo.owned.add(info.resource);
+                        return false;
+                    }
+                });
+            }
+        }
+
+        // Resolve inverses from ownedBy list
+        for (ResourceInfo info : infos.valueCollection()) {
+            for (int i = 0; i < info.owned.size(); i+=2) {
+                int object = info.owned.get(i+1);
+                ResourceInfo inf = infos.get(object);
+                if (inf != null) {
+                    info.ownedBy.remove(inf);
+                }
+            }
+        }
+        
                TreeMap<String,ResourceInfo> order = new TreeMap<>();
                for(ResourceInfo info : infos.valueCollection())
                        order.put(info.name, info);
 
-               for(ResourceInfo info : order.values())
-                       printURI(graph, info, true, 0);
+               for(ResourceInfo info : order.values()) {
+                       String uri = printURI(graph, info, true, 0, false);
+                       if (uri != null)
+                           output.append(uri);
+               }
 
-               for(ResourceInfo info : order.values())
-                       if(!info.hasURI && info.owner < 0)
-                               printURI(graph, info, false, 0);
+               for (ResourceInfo info : order.values()) {
+                   if (!info.hasURI && info.ownedResourcesWithPredicates.size() != 1) {
+                       String uri = printURI(graph, info, false, 0, false);
+                       if (uri != null)
+                           output.append(uri);
+                   }
+               }
+//             for(ResourceInfo info : order.values())
+//                     if(!info.hasURI && info.owner < 0)
+//                             printURI(graph, info, false, 0);
 
                StringBuilder refs = new StringBuilder();
                for(String ontology : referencedOntologies) {
                        String key = ontologies.get(ontology);
                        refs.append(key + " = <" + ontology + ">\n");   
                }
+               if (!referencedOntologies.isEmpty())
+                   refs.append("\n");
                output.insert(0, refs.toString());
                
        }
 
-       public static String print(TransferableGraph1 tg) throws Exception {
+    public static String print(TransferableGraph1 tg) throws Exception {
                StringBuilder b = new StringBuilder();
                new PrettyPrintTG(b).prettyPrint(tg);
                return b.toString();
index 4b113fa499b6bc1208d64b62e2be5be66713cc10..a7b92c8d015727880d256a9c17494bed54b70ce9 100644 (file)
@@ -71,6 +71,9 @@ public class TransferableGraphUtils {
                String[] tokens = uri.substring("http://".length()).split("/");
                for(String token : tokens) {
                        identity = findExternalWithNameAndParent(tg, identity.resource, token);
+                       if (identity == null) {
+                           return null;
+                       }
                }
                return identity;
                
index b725d6c74afca7914d62fb38909fb1a85c7e4209..19e83d30b571a7dfd9cf197090b1fecbe72939ea 100644 (file)
@@ -343,6 +343,7 @@ importJava "org.simantics.db.layer0.util.Layer0Utils" where
     listOntologies :: () -> <ReadGraph> [Resource]
     emptyTrashBin :: () -> <Proc> ()
     purgeDatabase :: () -> <Proc> ()
+    prettyPrintResource :: Resource -> <ReadGraph> String
 
     @private
     @JavaName copyTo