Hide Forgot
At the moment I primarily work on topics in a Content Spec. I'd like to be able to click on my Content Spec, and then see it rendered as a list of its topics - just like a search filter result. At the moment I emulate this behaviour by tagging all the topics in a Content Spec with a tag that causes this behaviour to manifest. However, as I add new topics the topics order by Topic ID, and not by their location in the Content Spec. I'd like the logical unit of organisation (grouping and sequencing) to be the Content Spec, so that changes to the spec are reflected in the skynet search results.
I'll assign this bug to Lee for the initial implementation. The code that is used to parse a spec will have to be made available in a jar file that can be included with Skynet. Something like: // ContentSpecProcessor would be the class that holds the CSP logic final ContentSpecProcessor csp = new ContentSpecProcessor(); // Point it at a content spec csp.parse(topicId); // Get the list of topics referenced by the spec final List<Integer> specTopics = csp.getReferencedTopicIds(); The above is just an example - I just need to be able to create a class that exposes the elements of a content spec. Once I can get those properties, a spec can be used as a search field.
I believe that I've implemented everything that is needed. You can download the Jars from the source code at http://sourceforge.net/p/csprocessor/code/104/tree/branches/lnewson/csprocessor/ (You'll probably need to get the latest revision this link points to REV 104) There are three jars, one is for accessing the csprocessor via REST and the other two contain the classes required. The csprocessor-skynet.jar is the same file as csprocessor.jar minus the Constants file that already resides in Skynet. Below is a snippet to parse a content spec and then pull out the Skynet topics it references if everything is okay. ------------------------------------------------------------------------- final ContentSpecParser csp = new ContentSpecParser(); /* * Parse the Content Spec which is stored in the XML component of a Topic. */ final List<Integer> topicIds; try { if (csp.parse(topic.getXml())) { topicIds = csp.getReferencedTopicIds(); } else { topicIds = new ArrayList<Integer>(); } } catch (Exception e) { e.printStackTrace(); } ------------------------------------------------------------------------ If the parser throws an Exception then it is something that wasn't expected. (ie BufferedReader.readLine() throwing an IOException). If the parser returns false then it means that there is something syntactically wrong with the Content Specification and therefore may not have been fully passed (The only case where it shouldn't fully parse is if the indentation is incorrect). I suspect that in future revisions the constructor will change to take in a URL to be able to access the REST Interface of skynet. Atm the parser doesn't do any requests to REST. The main reason for this is when I finish Topic Maps (see Bug #752710) the only way to get the ID's and parse it properly will be to pull the Map from the server via REST. Also passing the bug over to you now Matt.
Not sure how you're planning to present this, but one possibility that would be tres useful would be if it looked just like the Content Spec, with the indentation and everything, but each item was hyperlinked so that you can open the topic record. That way you see everything in the structure of the output, rather than just as a flat list.
To go with Josh's comment I should mention that the list returned by that function doesn't preserve the order of the Topics.
This is two different issues. The library provided by Lee will allow me to use the topics referenced by a spec as part of a search criteria. This means you specify a spec as part of a search, and the result is the same as every other topic search through skynet. A rendered view of the spec (with links and whatnot) is something else entirely.
Line 216 of the ContentSpecParser.java file bombs because the user is null.
Fixed at Revision 107. Cause: Recently new addition that I forgot to test, as such the parser was trying to read the username from a null variable. Consequence: The parser would throw a NullPointerException. Fix: Added a check if the user is null.
This has been out for quite some time and I know has been used on multiple occasions of late. So going to set this to CLOSED CURRENTRELEASE.