]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.help.core/src/org/simantics/help/core/HelpUtils.java
merged svn revision 33114 and added desktop and help plugins
[simantics/platform.git] / bundles / org.simantics.help.core / src / org / simantics / help / core / HelpUtils.java
diff --git a/bundles/org.simantics.help.core/src/org/simantics/help/core/HelpUtils.java b/bundles/org.simantics.help.core/src/org/simantics/help/core/HelpUtils.java
new file mode 100644 (file)
index 0000000..730fd42
--- /dev/null
@@ -0,0 +1,337 @@
+package org.simantics.help.core;\r
+\r
+import java.io.IOException;\r
+import java.io.StringWriter;\r
+import java.net.URL;\r
+import java.net.URLDecoder;\r
+import java.nio.charset.StandardCharsets;\r
+import java.nio.file.Files;\r
+import java.nio.file.Path;\r
+import java.nio.file.StandardOpenOption;\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Map.Entry;\r
+import java.util.TreeMap;\r
+\r
+import org.eclipse.mylyn.wikitext.core.parser.MarkupParser;\r
+import org.eclipse.mylyn.wikitext.core.parser.builder.HtmlDocumentBuilder;\r
+import org.eclipse.mylyn.wikitext.mediawiki.core.MediaWikiLanguage;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.eclipse.ui.help.IWorkbenchHelpSystem;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.BindingException;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;\r
+import org.simantics.db.exception.ServiceException;\r
+import org.simantics.document.base.ontology.DocumentationResource;\r
+import org.simantics.help.HelpResources;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingUtils;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+\r
+import winterwell.markdown.pagemodel.MarkdownPage;\r
+\r
+public class HelpUtils {\r
+\r
+    public static Resource createHelpLibrary(WriteGraph graph, Resource parent) throws DatabaseException {\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        HelpResources HELP = HelpResources.getInstance(graph);\r
+        Resource library = graph.newResource();\r
+        graph.claim(library, L0.InstanceOf, null, HELP.HelpLibrary);\r
+        graph.addLiteral(library, L0.HasName, L0.NameOf, "Help Library", Bindings.STRING);\r
+        graph.claim(parent, L0.ConsistsOf, L0.PartOf, library);\r
+        return library;\r
+    }\r
+    \r
+    public static Resource createHelpTutorial(WriteGraph graph, Resource parent, String name) throws DatabaseException {\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        HelpResources HELP = HelpResources.getInstance(graph);\r
+        Resource tutorialFile = graph.newResource();\r
+        graph.claim(tutorialFile, L0.InstanceOf, null, HELP.TutorialFile);\r
+        graph.addLiteral(tutorialFile, L0.HasName, L0.NameOf, name, Bindings.STRING);\r
+        graph.claim(parent, L0.ConsistsOf, L0.PartOf, tutorialFile);\r
+        return tutorialFile;\r
+    }\r
+\r
+    public static List<Path> collectHelps(ReadGraph graph, Resource indexRoot) throws DatabaseException {\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        HelpResources HELP = HelpResources.getInstance(graph);\r
+        List<Resource> tutorialFiles = ModelingUtils.searchByType(graph, indexRoot, HELP.TutorialFile);\r
+        if (tutorialFiles.isEmpty())\r
+            return Collections.emptyList();\r
+        List<Path> result = new ArrayList<>(tutorialFiles.size());\r
+        for (Resource tutorialFile : tutorialFiles) {\r
+            StringBuilder sb = new StringBuilder();\r
+            \r
+            htmlHead(sb, graph.getRelatedValue2(tutorialFile, L0.HasName, Bindings.STRING));\r
+            sb.append(HelpUtils.markdownToHtml(graph, tutorialFile));\r
+            htmlHeadClose(sb);\r
+            \r
+            String indexRootURI = graph.getURI(indexRoot);\r
+            String indexRootName = graph.getRelatedValue2(indexRoot, L0.HasName, Bindings.STRING);\r
+            String tutorialFileURI = graph.getURI(tutorialFile);\r
+            String suffix = tutorialFileURI.substring(indexRootURI.length());\r
+            try {\r
+                if (suffix.startsWith("/"))\r
+                    suffix = suffix.substring(1);\r
+                suffix = URLDecoder.decode(suffix, StandardCharsets.UTF_8.name());\r
+                Path outputPath = Activator.getHtmlDirectory().resolve(indexRootName).resolve(suffix + ".html");\r
+                createDirsRec(outputPath.getParent());\r
+                if (!Files.exists(outputPath))\r
+                    Files.createFile(outputPath);\r
+                Files.write(outputPath, sb.toString().getBytes(StandardCharsets.UTF_8), StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);\r
+                result.add(outputPath);\r
+            } catch (IOException e) {\r
+                e.printStackTrace();\r
+            }\r
+        }\r
+        return result;\r
+    }\r
+\r
+    private static void createDirsRec(Path path) throws IOException {\r
+        Path parent = path.getParent();\r
+        if (!Files.exists(parent)) {\r
+            createDirsRec(parent);\r
+        }\r
+        if (!Files.exists(path))\r
+            Files.createDirectory(path);\r
+    }\r
+\r
+    public static Map<String, List<Path>> collectHelpsFromSharedLibraries(ReadGraph graph) throws DatabaseException {\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        Collection<Resource> sharedLibraries = graph.syncRequest(new ObjectsWithType(graph.getRootLibrary(), L0.ConsistsOf, L0.SharedOntology));\r
+        if (sharedLibraries.isEmpty())\r
+            return Collections.emptyMap();\r
+        Map<String, List<Path>> result = new HashMap<>(sharedLibraries.size());\r
+        for (Resource library : sharedLibraries) {\r
+            String libraryName = graph.getRelatedValue2(library, L0.HasName, Bindings.STRING);\r
+            List<Path> paths = collectHelps(graph, library);\r
+            result.put(libraryName, paths);\r
+        }\r
+        return result;\r
+    }\r
+    \r
+    public static Map<String, Path> collectWidgetReferencesFromSharedLibraries(ReadGraph graph) throws DatabaseException {\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        Collection<Resource> sharedLibraries = graph.syncRequest(new ObjectsWithType(graph.getRootLibrary(), L0.ConsistsOf, L0.SharedOntology));\r
+        if (sharedLibraries.isEmpty())\r
+            return Collections.emptyMap();\r
+        Map<String, Path> result = new HashMap<>(sharedLibraries.size());\r
+        for (Resource library : sharedLibraries) {\r
+            String html = createWidgetReference(graph, library, "Widget Reference");\r
+            String indexRootName = graph.getRelatedValue2(library, L0.HasName, Bindings.STRING);\r
+            try {\r
+                Path outputPath = Activator.getHtmlDirectory().resolve(indexRootName).resolve("widgetReference.html");\r
+                createDirsRec(outputPath.getParent());\r
+                if (!Files.exists(outputPath))\r
+                    Files.createFile(outputPath);\r
+                Files.write(outputPath, html.getBytes(StandardCharsets.UTF_8), StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING);\r
+                result.put(indexRootName, outputPath);\r
+            } catch (IOException e) {\r
+                e.printStackTrace();\r
+            }\r
+        }\r
+        return result;\r
+    }\r
+    \r
+    private static void htmlHead(StringBuilder sb, String title) {\r
+        sb.append("<!DOCTYPE html PUBLIC \"-//IETF//DTD HTML//EN\">\n");\r
+        sb.append("<html><head><title>" + title + " Tutorial</title>\n");\r
+        sb.append("<link rel=\"Stylesheet\" type=\"text/css\" media=\"all\" href=\"../style.css\">\n");\r
+        sb.append("</head>\n");\r
+        sb.append("<body style=\"background-color: white;\">\n");\r
+        sb.append("<h1 align=\"center\">" + title + "</h1>\n");\r
+        sb.append("<hr>\n");\r
+    }\r
+    \r
+    private static void htmlHeadClose(StringBuilder sb) {\r
+        sb.append("</body></html>\n");\r
+    }\r
+\r
+    public static String createWidgetReference(ReadGraph graph, Resource indexRoot, String title) throws DatabaseException {\r
+\r
+        String ontologyDesc = NameUtils.getSafeLabel(graph, indexRoot);\r
+        \r
+        StringBuilder sb = new StringBuilder();\r
+        \r
+        sb.append("<!DOCTYPE html PUBLIC \"-//IETF//DTD HTML//EN\">\n");\r
+        sb.append("<html><head><title>" + ontologyDesc+ " Widget Reference</title>\n");\r
+        sb.append("<link rel=\"Stylesheet\" type=\"text/css\" media=\"all\" href=\"../style.css\">\n");\r
+        sb.append("</head>\n");\r
+        sb.append("<body style=\"background-color: white;\">\n");\r
+        sb.append("<h1 align=\"center\">" + ontologyDesc+ "</h1>\n");\r
+        sb.append("<h2 align=\"center\">Widget Reference</h2>\n");\r
+        sb.append("<hr>\n");\r
+        sb.append("<h1 align=\"center\">" + title + "</h1>\n");\r
+        \r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
+        DocumentationResource DOC = DocumentationResource.getInstance(graph);\r
+        \r
+        List<Resource> types = ModelingUtils.searchByType(graph, indexRoot, DOC.DocumentComponentType);\r
+        for(Resource type : types) {\r
+\r
+            \r
+            String label = NameUtils.getSafeLabel(graph, type);\r
+\r
+            sb.append("<h2><a name=\"" + label + "\"></a>" + label + "</h2>\n");\r
+            sb.append("<h3>Description</h3>\n");\r
+\r
+            String desc = graph.getPossibleRelatedValue(type, L0.HasDescription);\r
+            if(desc == null) desc = "";\r
+            \r
+            sb.append("<p>" + WikiParser.parseToHtml(desc, false) + "</p>\n");\r
+            \r
+            sb.append("<h3>Base Types</h3>\n");\r
+            \r
+            Map<String,String> names = new HashMap<String,String>();\r
+\r
+            for(Resource r : graph.getSupertypes(type)) {\r
+\r
+                if(graph.isInheritedFrom(r, STR.Component)) {\r
+                    \r
+                    String label2 = NameUtils.getSafeLabel(graph, r);\r
+                    String name = graph.getRelatedValue(r, L0.HasName);\r
+                    //if("Component".equals(name)) continue;\r
+                    if("Element".equals(name)) continue;\r
+                    if("DefinedElement".equals(name)) continue;\r
+                    if("PrimitiveComponent".equals(name)) continue;\r
+                    if("DocumentComponent".equals(name)) continue;\r
+                    \r
+                    names.put(name, label2);\r
+\r
+                }\r
+                \r
+            }\r
+\r
+            for(Map.Entry<String, String> entry : names.entrySet()) {\r
+                String stuff = "predefined/baseWidgets.html#";\r
+                sb.append("<a href=\"" + stuff + entry.getKey() + "\">" + entry.getValue() + "</a>\n");\r
+                //sb.append("<a href=\"baseWidgets.html#" + entry.getKey() + "\">" + entry.getValue() + "</a>\n");\r
+            }\r
+\r
+            sb.append("<h3>Properties</h3>\n");\r
+            sb.append("<table style=\"width: 100%;\" border=\"1\" cellpadding=\"0\" cellspacing=\"0\">\n");\r
+            sb.append("<tbody>\n");\r
+            sb.append("  <tr style=\"background-color: silver;\">\n");\r
+            sb.append("  <td valign=\"top\"><br><strong>Property Name</strong></td>\n");\r
+            sb.append("  <td valign=\"top\"><br><strong>Type</strong></td>\n");\r
+            sb.append("  <td valign=\"top\"><br><strong>Default Value</strong></td>\n");\r
+            sb.append("  <td valign=\"top\"><br><strong>Description</strong></td>\n");\r
+            sb.append("  </tr>\n");\r
+            \r
+            Map<String, Resource> propertyMap = new TreeMap<String, Resource>();\r
+            \r
+            for(Resource ass : graph.getObjects(type, L0.Asserts)) {\r
+                \r
+                Resource object = graph.getSingleObject(ass, L0.HasObject);\r
+                \r
+                if(graph.isInstanceOf(object, L0.SCLValue)) continue;\r
+                if(graph.isInstanceOf(object, L0.Function)) continue;\r
+                if(graph.isInstanceOf(object, L0.ExternalValue)) continue;\r
+\r
+                Resource pred = graph.getSingleObject(ass, L0.HasPredicate);\r
+                String pName = NameUtils.getSafeLabel(graph, pred);\r
+                propertyMap.put(pName, ass);\r
+            }\r
+            \r
+            for (Entry<String, Resource> entry : propertyMap.entrySet()) {\r
+                Resource ass = entry.getValue();\r
+                Resource object = graph.getSingleObject(ass, L0.HasObject);\r
+                \r
+                Resource pred = graph.getSingleObject(ass, L0.HasPredicate);\r
+                String pName = NameUtils.getSafeLabel(graph, pred);\r
+                String valueType = graph.getPossibleRelatedValue(pred, L0.RequiresValueType);\r
+\r
+                Object jObject = graph.getValue(object);\r
+                String objectName = jObject.toString();\r
+                if(jObject.getClass().isArray()) {\r
+                    Class<?> c1 = jObject.getClass().getComponentType();\r
+                    boolean p1 = c1.isPrimitive();\r
+                    if (!p1)\r
+                        objectName = Arrays.toString((Object[])jObject);\r
+                    if (boolean.class.equals(c1))\r
+                        objectName = Arrays.toString((boolean[])jObject);\r
+                    else if (byte.class.equals(c1))\r
+                        objectName = Arrays.toString((byte[])jObject);\r
+                    else if (int.class.equals(c1))\r
+                        objectName = Arrays.toString((int[])jObject);\r
+                    else if (long.class.equals(c1))\r
+                        objectName = Arrays.toString((long[])jObject);\r
+                    else if (float.class.equals(c1))\r
+                        objectName = Arrays.toString((float[])jObject);\r
+                    else if (double.class.equals(c1))\r
+                        objectName = Arrays.toString((double[])jObject);\r
+                }\r
+\r
+                String pDesc = graph.getPossibleRelatedValue(pred, L0.HasDescription);\r
+                if(pDesc == null) pDesc = "";\r
+                \r
+                sb.append("  <tr>\n");\r
+                sb.append("  <td valign=\"top\">" + pName + "</td>\n");\r
+                sb.append("  <td valign=\"top\">" + valueType + "</td>\n");\r
+                sb.append("  <td valign=\"top\">" + objectName + "</td>\n");\r
+                sb.append("  <td valign=\"top\">" + WikiParser.parseToHtml(pDesc, false) + "</td>\n");\r
+                sb.append("  </tr>\n");\r
+            }\r
+\r
+            sb.append("  </tbody></table><br>\n");\r
+        }\r
+\r
+        sb.append("</body></html>\n");\r
+        return sb.toString();\r
+    }\r
+    \r
+    public static void clearHelpTocCache() {\r
+        SimanticsTocProvider.clearTocCache();\r
+    }\r
+    \r
+    public static void saveHelpFileContents(WriteGraph graph, Resource helpFile, String currentText) throws BindingException, ManyObjectsForFunctionalRelationException, ServiceException {\r
+        HelpResources HELP = HelpResources.getInstance(graph);\r
+        graph.claimLiteral(helpFile, HELP.HelpFile_contents, currentText, Bindings.STRING);\r
+    }\r
+    \r
+    public static String readHelpFileContents(ReadGraph graph, Resource helpFile) throws DatabaseException {\r
+        HelpResources HELP = HelpResources.getInstance(graph);\r
+        String content = graph.getPossibleRelatedValue2(helpFile, HELP.HelpFile_contents, Bindings.STRING);\r
+        return content != null ? content : "";\r
+    }\r
+    \r
+    public static String markdownToHtml(ReadGraph graph, Resource tutorialFile) throws DatabaseException {\r
+        HelpResources HELP = HelpResources.getInstance(graph);\r
+        String markdown = graph.getRelatedValue2(tutorialFile, HELP.HelpFile_contents, Bindings.STRING);\r
+        MarkdownPage page = new MarkdownPage(markdown);\r
+        return page.html();\r
+    }\r
+    \r
+    public static URL getHelpBrowserUrl() {\r
+        IWorkbenchHelpSystem helpSystem = PlatformUI.getWorkbench().getHelpSystem();\r
+        URL url = helpSystem.resolve("", false);\r
+        return url;\r
+    }\r
+\r
+    private static class WikiParser {\r
+        \r
+        private static MarkupParser markupParser = new MarkupParser(new MediaWikiLanguage());\r
+        \r
+        private WikiParser() {}\r
+        \r
+        public static String parseToHtml(String wiki, boolean asDocument) {\r
+            StringWriter writer = new StringWriter();\r
+            HtmlDocumentBuilder builder = new HtmlDocumentBuilder(writer);\r
+            markupParser.setBuilder(builder);\r
+            markupParser.parse(wiki, asDocument);\r
+            return writer.toString();\r
+        }\r
+    }\r
+}\r