IG at the San Francisco Java UG on Tuesday August 14th

I (Adrian Blakey) got signed up to speak about Infogrid at the San Francisco Java User Group. As of this morning it looks like the event had 162 171 people signed up.

I’ll borrow Johannes slides for the talk, and give a simple demo using a database of National Provider Identifiers to show off probes and listeners. Please come up to me at the meeting and say hi, I am sure there will be much that I either don’t cover or quite frankly do not understand well enough about IG to give it its due.

From MVC to MOVE

Conrad Irvin has a nice post on how to fix some of the problems with the ubiquitous MVC (“Model View Controller”) architecture that’s used in so many user interface frameworks, from rich clients to web apps.

He calls the model MOVE, i.e Models, Operations, Views and Events: his Models capture the information in the application, Views render it and, when the user interacts with a View, raise Events that are received by Operations that modify the Model.

In InfoGrid, we obviously use the word model more precisely by distinguishing what we call a model (the schema) and the graph of objects (the data) — together what he calls the Model.

Viewlets are exactly what he means with a View.

Where it’s getting interesting is Operations and Events: since the InfoGrid HttpShell has been supporting HttpShellHandlers, these handlers are almost exactly what he describes as operations. We can think of the symbolic names of handlers as used in a JSP page as the Events in his model, and the binding of symbolic names to handlers as the mapping between Events and Operations.

So we like his description of an improved MVC model, and offer an example where it has been implemented.

InfoGrid 2.9.5 Released

It’s been a while since the last release, but why change if users are been generally happy with it ;-) … Here’s what’s new:

Highlights:

  • Native support for currency values (e.g. $1.23 USD)
  • Even simpler JSON generation
  • StringDataTypes can now carry a regular expression, which is checked before assignment (e.g. makes it impossible to assign a String that isn’t to a property that must contain an e-mail address)
  • Support for cascading delete
  • InfoGrid compilation is now reported to work on Windows
  • Multi-tenancy support for LID
  • More flexible handling of HTTP status codes in Probe framework (e.g. what should happen upon a redirect)
  • Extensions to custom JEE tags and HttpShell to make JSP programming with InfoGrid even simpler, e.g. simple tags to create Javascript-based overlay forms
  • Improved error reporting
  • Additional tests
  • Lots of small usability improvements and bug fixes

Here are the gory details:

Core:

  • ModuleAdvertisementSerializer to generate relative paths to JARs
  • more types of MeshObjectSelector
  • added getLocalId to NetMeshObjectIdentifier
  • added guessFromExternalForm to IdentifierFactory
  • use “” not null for localId of home object
  • Augmented set of pre-defined BlobDataTypes
  • Improved BlobDataType to check for MIME compatibility with regexes
  • added CurrencyValue and CurrencyDataType to represent money as a primitive type
  • added convenience method to MeshObject: determine whether the relationship to a neighbor MeshObject is blessed with a certain RoleType
  • Moved OnDemandTransaction from HttpShell into utils
  • implemented cascading delete support
  • added TimeStampValue.earlierOf and TimeStampValue.laterOf for convenience
  • Special value NOW for TimeStampValue parsing
  • regex can be be specified for StringDataTypes
  • added AbstractDelegatingLocalizedRuntimeException for symmetry and completeness
  • better error reporting for TransactionActionExceptions
  • Explicitly set latin1 character set in MySQL store to avoid key size error when the default character set is multi-byte.
  • TransactionAction.execute() now does not take a Transaction parameter any more, but provides it as a member variable
  • check raw id even when guessing MeshObjectIdentifier
  • when there’s a ParseException during parsing of store content, don’t return null but throw NoSuchElementException
  • Added MeshObjectHelper for simpler JSP programming with TypedMeshObjectFacades
  • Carry specify exceptions keyed by failed MeshObjectIdentifiers in MeshObjectAccessException, instead of swallowing all exceptions other than the first
  • MeshObjectsNotFoundException is not a subclass of MeshObjectAccessException any more
  • Correct singular/plural error messages for MeshObjectAccessException and MeshObjectsNotFoundException
  • NetMeshObjectAccessException now carries redirect NetMeshObjectAccessSpecifications
  • NetMeshObjectAccessSpecification is now an Identifier
  • Migrated sweeping functionality from the various MeshBase implementations into Sweeper. The policy functionality of Sweeper became SweepPolicy.
  • Better pingpong debugging support
  • created MeshObjectSet.hasSameContent
  • upgrade to warn if MySQL database cannot be detected/created
  • Id column in MySQL needs to be case-sensitive
  • don’t report exception in rollback that isn’t an error
  • default expiration for UnnecessaryReplicasSweepPolicy
  • Allow the sweep of a single MeshObject
  • MeshObject.delete and sub-methods have no business to throw NotPermittedException
  • Non-semantic “kill” of a ShadowMeshBase
  • Kill button in ShadowAwareAllMeshBasesViewlet
  • No need for public method initiateCeaseCommunications on Proxy
  • Don’t try to talk to Proxies when NetMeshBase is dead
  • Tolerate some IsDeadExceptions when dead (duh)
  • Use default mime type for BlobValue when none is given when parsing StringRepresentation
  • Avoid that IsDeadException kills meaningful error message
  • support typefield XML attribute for StringDataTypes as well
  • added StringDataType for e-mail
  • fixed automatic merge problem
  • allow MeshObject.equals( TypedMeshObjectFacade ) for simplicity
  • use get_XXX pattern in TypedMeshObjectFacade for non-Properties/non-pseudo-Properties to avoid name clashes with code-generated setters
  • use get_XXX pattern in TypedMeshObjectFacade for non-Properties/non-pseudo-Properties to avoid name clashes with code-generated setters
  • renamed Rfc3339Util to DateTimeUtil and expanded to W3C timestamps
  • DefaultNetMeshBaseIdentifierFactory now uses pluggable “Scheme”s to support identifiers of various protocols, including http, https, file, xri, acct
  • renamed UnknownProtocolParseException to UnknownSchemeParseException
  • added ability to specify Maps in Resource files
  • When parsing NetMeshBaseIdentifiers, turn each String into canonical form as well, e.g. hTTp: and http:
  • added toColloquialExternalForm() to Identifier; more sane
  • removed IdentifierStringifier.toColloquialIdentifier()
  • use guessFromExternalForm in more places for more tolerance (e.g. when reading from Store to be more tolerant of Scheme changes)
  • be more tolerant of Exceptions when restarting MeshBases; try best-effort
  • Better logging of start / die of InfoGridWebApps
  • when resetting PingPong, only increment token by 1
  • more defensive programming if Storage layer is corrupt
  • refactor message sending framework to always deliver all received messages together instead of singly
  • merge two XprisoMessages before processing if possible
  • added ByPropertyValueSelector and PropertyComparisonOperator
  • NotRelatedException not thrown any more when testing whether two MeshObjects are related by a given RoleType; was counter-intuitive and pedantic
  • StringRepresentationParameters must always be given.
  • Make it easier to generate MeshObjectIdentifiers with different lengths
  • upgraded Postgresql JDBC for 64bit support
  • Netbeans 7 support
  • Make sure Threadpool is always cleanly shut down. Now Tomcat won’t hang occasionally after undeploy.
  • support custom regex violation error messages for PropertyTypes that specify regular expressions
  • refactored L10Map into L10PropertyValueMap and L10StringMap, moved to utils package
  • more HTML class declarations in BlobValue HTML
  • added invert method to most MeshObjectSelectors
  • added MeshObjectSet.subset convenience method
  • Don’t include dead MeshObjects in MeshObjectSets
  • factored out ExternalCommand so invoking an external process becomes simpler
  • default MeshObjectIdentifier to contain _ instead of ~

Identity-related:

  • AccountManager needs a site parameter for determining account to support multi-tenancy
  • generate login event even if only the session gets renewed
  • XrdsProbe to cache the XRDS file
  • added content and content type as parameters to XmlProbe interface; enables XrdsProbe to cache the XRDS file
  • added getGroupNames to LidAccount
  • check group membership by group identifier as well as group name
  • also check group membership by groups set as request attribute
  • factored out some symbolic OpenID parameter names
  • fix when associations expire
  • Better integrated AccessManager and ThreadIdentityManager
  • root may do anything in AclBasedAccessManager
  • Split AclBasedSecurity into two: an ACL-based AccessManager implementation that does not rely on Guards, and an AccessManager implementation that evaluates Guards but is independent on a particular model (such as the AclBasedSecurity model)
  • Eliminated org.infogrid.model.AclBasedSecurity, and instead introduced org.infogrid.meshbase.security.aclbased, which also includes a model
  • DelegatingAccessManager now supports delegating to multiple other AccessManagers, all of which must agree
  • added ThreadIdentityManager.suExec
  • When there isn’t a ProtectionDomain, it’s free for all in AclBasedAccessManager
  • moved org.infogrid.model.SecurityTest into the attic; currently not used
  • added expiring credentials to AuthenticationStatus
  • expired OpenID associations throw OpenIdAssociationExpiredException
  • OpenID dumb mode fixes
  • Added getCarriedExpiredCredentialTypes to LidClientAuthenticationStatus
  • added org.infogrid.lid.model.account/Account_LastLoggedIn which can come in handy
  • Removed Account Status value CREATED — not particularly useful and would have needed update logic
  • credential values are now separate from LidAccount, e.g. the StoreLidPasswordCredentialType knows where to look for the password
  • don’t need LidCredentialType.isRemote any more
  • allow password change from StoreLidPasswordCredentialType
  • removed realm from LID; never quite used
  • better support for multi-tenancy / virtual hosts in LID: carry siteIdentifier around in more places
  • distinguish one-time-tokens from other types of credentials in LID
  • more methods for setting, checking, resetting password credentials
  • support that MeshObject can own itself in AclUtils
  • A little helper utility to generate secret keys

Model-related:

  • Code-generate an entry for the SubjectArea itself, too
  • exactly one SubjectArea element is expected in each model element in the model XML
  • Added HTTP status code and location properties to WebResource
  • minor rename of SubjectArea user-visible name

Probe-related:

  • Handle HTTP redirects better when encountered by Probes; existing behavior should be unchanged however
  • Do not throw FactoryException as a direct cause of NetMeshObjectAccessException but its cause instead
  • Introduced ProbeException.HttpRedirectResponse
  • Added NetMeshBaseRedirectException, so ProbeException.HttpRedirectResponse does not need to be moved up to module org.infogrid.kernel.net
  • Introduced HttpMappingPolicy that enables different policies for mapping HTTP non-OK status codes into InfoGrid; default remains the same behavior
  • Change in API to set up ProbeManagers etc.: ProbeDirectory passed to ProbeManager instead of ShadowMeshBaseFactory, then ShadowMeshBaseFactory is notified where ProbeManager can be found
  • ProbeException.HttpErrorResponse not needed any more
  • Support HTTP redirects that give relative URLs as Location, against the HTTP spec (I’m looking at you, Google)
  • HttpMappingPolicy has moved from ProbeManager to ProbeDirectory
  • Fixes issue where wrong HttpMappingPolicy was set upon restore of Shadow from disk
  • Throw exception if ProbeManager is configured without a ProbeDirectory
  • added basic XRD support to InfoGrid
  • added acct: as one of the basic protocols supported by NetMeshBaseIdentifier
  • added Webfinger support
  • Don’t throw ProbeException.DontHaveNonXmlStreamProbe if the found content is of length zero

Viewlet/GUI-related:

  • Renamed NotIfViewletState to NotIfViewletStateTag for consistency
  • throw correct error message if no subject
  • fix status in AbstractSetIterateTag
  • colloquial=true by default
  • by default, sort alphabetically in TreeIterateTag
  • fix display of <HOME> for home object broken in last checkin
  • added potentiallyShorten to WebContextAwareMeshObjectIdentifierStringifier
  • instrument to track HTTP client-side calls
  • trim strings first to deal with sloppy JSP writing
  • added request property to JeeMeshObjectsToView
  • change default app server to Tomcat6
  • pass SaneUrl through to ViewletFactory, so it can access request attributes
  • created org.infogrid.jee.security.aclbased tag library for AclBasedSecurity Subject Area
  • added TextStructuredResponseSection.containsContent
  • replaced ViewletAlternativesTag.js with more general-purpose ToggleCssClass.js
  • support redirect to newly created object in HttpShell
  • Created BracketTags, which allow conditional generation of, say, <ul> and </ul> tags depending on whether or not the content tag has any non-whitespace content.
  • factored out AbstractSaneRequest.urlWithoutMatchingArguments for easier reusability
  • trim entered identifiers before trying to resolve them in HttpShellFilter
  • Better error reporting for HttpShell
  • IncludeViewletTag more robust if path not specified
  • Removed the List<Throwable> in request attribute for collecting processing exceptions; now abstracted into new interface ProblemReporter
  • Allow null identifiers for create access verb in HttpShell again
  • hyperlink on UnsafePostException’s message
  • TitleTag to use a separate section in the StructuredResponse
  • default mechanism for TitleTag with Viewlet name and app name, can be overridden with TitleTag
  • <tmpl:title> tag prints <title> tags itself
  • fixed userVisibleName on Viewlet
  • JeeViewlets’ default POST URL used to sometimes leave out reached MeshObjects, which would list all found-by-traversal MeshObjects after post, which was very confusing. Removed traversal spec in case there are no reached MeshObjects
  • Pass subject’s userVisibleString into default Viewlet title construction.
  • Created InvalidViewletActionException.
  • enable logging of when InfoGridWebApps start and stop
  • added HttpShellHandler to HttpShell
  • rollback Transaction if there is an exception during execution by HttpShell
  • support for radiobox-driven “which MeshObject should I be related to” relate/unrelate from the HttpShell
  • Added sweep and accessLocally to HttpShell HTML
  • Created ProxyTag in analogy to emitting other objects like MeshObjects etc.
  • Sweep support for the HttpShell
  • Added limit parameter to SetIterateTags in analogy to SQL limit
  • Added MeshObjectSetIterateBeyondLimitTag that gets invoked when a MeshObjectSet iteration stops due to a limit parameter so the JSP can display a “more” link or something like that
  • display trailing slash on URLs even if isColloquial; if not, user cannot distinguish URLs with and without trailing slashes
  • added IfNullTag and NotIfNull tag
  • allow to set properties via the HttpShell at the same time the MeshObject is only being created
  • working on allowing to set properties via the HttpShell at the same time the MeshObject is only being created
  • added allowNull attribute to PropertyTag to remove “remove” label for optional properties when so needed
  • fix ignore=”true” bug in MeshObjectTag
  • implemented a “JSP subroutine” set of custom tags
  • allow TypedMeshObjectFacade in place of any MeshObject for JSP custom tags; makes life simpler
  • use ‘block’ instead of ‘inline’ for create label in PropertyTags, so CSS can be used to move label vertically
  • added the just-completed Transactions to the invocation of HttpShellHandler, so implementations have a chance to understand what happened
  • added deleted MeshObjects to variable map passed to HttpShellHandler
  • tag to easily report a problem into the error log
  • tags to safeguard JSPs against inadvertent invocation by the wrong user or with the group user groups
  • support AccountStatus APPLIEDFOR and REFUSED
  • change default HTML title if Viewlet reports error; that way we don’t accidentially leak information if there is an access control problem
  • Re-implemented CSRF remedy: now match cookie and form instead of issuing form tokens
  • use lowercase cookie names
  • Added NotIfErrorsTag and NotIfInfoMessagesTag
  • Use StringRepresentation framework to format the label String for null PropertyValues
  • augmented HttpShellHandler to have invocable method before, after, at the beginning and at the end of Transactions
  • MeshType may be given directly in PropertyIterateTag
  • Change where <HOME> special identifier is defined. Stringifying MeshObjectIdentifier for HomeObject now produces “”, while stringifying MeshObject produces <HOME>
  • HttpShell now recognizes “not set” value because “” is now a valid value for a MeshObjectIdentifier
  • added JspoXXXTags
  • removed now unnecessary org.infogrid.jee.store project
  • carry incoming request in DefaultJeeNetMeshObjectsToView
  • Allow both bean and identifiers in AbstractRelatedTag and subclasses
  • always use multi-part encoding for Jspo forms so file uploads are always possible
  • make JSP tags more consistent that use MeshObjects: can now specify MeshObject directly, MeshObjectIdentifier (direct and as String), or name of bean
  • added MeshObjectBlessedByTag
  • allow optional parameters on Jspo and Jspf tags
  • Support $1.23 in addition to 1.23 USD for CurrencyValue
  • support different capitalizations for MeshObjectBlessedByTag
  • SingleMemberTraversalTag for convenience
  • additional keywords for HttpShell
  • allow HttpShell to override/specify direction of a redirect after shell execution
  • additional callback afterAccess for HttpShell
  • allow immediate activation of called JspoTag through property on call
  • Added Json viewlet. New viewlet that will write a direct acyclic object graph in Json to level n.
  • added custom tag that makes it easy to iterate over the intersection of two traversal sets
  • allow MeshObjectBlessedByTag to write to a variable instead of to stdout
  • rollback transaction when HttpShellHandler throws HttpShellException
  • added MissingArgumentException that turns out to be generally useful
  • Created custom tags to help matching URL arguments easily
  • fixed incorrect processing of RuntimeException in HttpShell (particularly from HttpShellHandlers)
  • DataType would sometimes invalidly truncate HTML output with maxLength specified. Hope this implementation is better.
  • slight refactoring of JeeViewlet-internal API to make it easier to remove URL parameters from Viewlet’s default Post URL

MeshWorld/NetMeshWorld-related:

  • Show number of MeshObjects in the MeshBase in AllMeshObjectsViewlet
  • round borders for webkit-based browsers too
  • NetMeshWorld has no business depending on AclBasedSecurity at this time
  • introduced property AnetMeshBase.ALLOW_NON_LOCAL_MESHOBJECT_CREATION to allow non-local NetMeshObject creation — useful for test instrumentation, for example
  • created ModuleInventoryViewlet
  • added app resource file to MeshWorld and NetMeshWorld
  • Added Sweeping button into NetMeshWorld.
  • Added ability to filter MeshBase content in AllMeshObjectsViewlet
  • Enable AllMeshObjectsViewlet to view empty sets.
  • Added properties file for Log4jConfigurationViewlet
  • add direct link to PropertySheetViewlet from AllMeshObjectsViewlet
  • Added filtering by home proxy to AllNetMeshObjectsViewlet
  • NetMeshWorld uses AllNetMeshObjectsViewlet, not AllMeshObjectsViewlet now
  • added “requires Javascript” via <noscript> to templates in example and test apps
  • Sort EntityTypes alphabetically in AllMeshObjectsViewlet

The Json Viewlet

A new viewlet was recently added to the build called JsonViwelet that renders a graph of objects in Javascript Object Notation (Json). It’s packaged in a new module called org.infogrid.jee.viewlet.json to isolate its dependency on “Jackson” – an open source Json parser, from the rest of the ig-ui modules, which is checked in to the ig-vendors package.

This viewlet was provided to help you write an Ajax user interface. Of course, it does not solve the whole problem of creating a modern browser experience which includes visually rendering objects in a browser window, and synchronizing them with the server running Infogrid. However it does kick-start the process and is one less issue to deal with.

There is already support for Json in the tree, from a Viewlet in the ig-ui MeshWorld test apps. called ObjectSetViewlet.jsp. As its name suggests it is a java server page implementation. It’s packaged conventionally in the web tree in v/viewlet/objectset/ObjectSetViewlet/text/json so that it can be dispatched when you provide a mime type of “text/json” in the lid-format parameter of the request URL. As its name suggests it’s dispatched on a collection of objects returned by traversing from the object identified in the request URL – e.g. http://localhost:8084/org.infogrid.meshworld.net/nnnnn?lid-format=viewlet:org.infogrid.jee.viewlet.objectset.ObjectSetViewlet&lid-format=mime:text/json&lid-traversal=org.foo.Test/Entity_Collects_AnotherEntity-S

This serves as a useful example for how to develop your own Json viewlets, however you could soon end up with several special purpose jsp viewlets that could say render the specific object in the request as Json, render it with and without its meta information and so on … These different rendering requirements are based on how you intend to use the objects into which the Json response gets transformed when it’s evaluated in the browser.

So it seemed like a better idea to provide a universal viewlet that could fulfill all these requirements by being passed URL arguments to control its behavior. It works by performing a transitive closure on the object graph from the object specified in the URL – without looping. Whenever a cycle is detected it writes the object’s “id”  but not its contents, to stub the graph so that the client has a reference it can deal with later.

Unless constrained by the arguments, its default behavior is to dump everything about every object that is encountered in the traversal. So be warned – if you have a very interconnected graph you could end up dumping the whole contests of your meshbase.

The JsonViewlet takes the URL arguments:

  • level=n|0 – 0 means no limit and will follow every relationship
  • dateenc=func|string – determines how Date is rendered, either as a function or String
  • ignoreblessing=entitytype_name_regex – names of blessings to be ignored
  • meta=[no|false]|[true|yes]|only – whether or not to dump meta information
  • trimsa=[yes|true]|[no|false] – trims the subject area name from the property names

Bold = default.

Level, determines the depth of the traversal. Since the object identifiers are returned for the next lower level you could provide code in your javascript client to later make another call to return the next levels in the graph.

Dateenc, controls how IG TimeStamp’s are rendered in json. Json does not provide a way to encode dates, so there is a choice to do this either as a string or as a javascript Date constructor method signature. They both work – you choose.

Ignoreblessing, has the effect of not dumping the values of the specified blessing. This is primarily useful for removing the Probe model properties which bless probed entities. This is control information that is probably not needed by a client – unless you are say writing a probe manager. You can pass it a regular expression or the fully qualified class name, and the argument can be repeated or comma-delimited to specify as many of these as you like.

Meta, gives you the option of either supressing the meta information or only dumping the meta information about an object. Javascript is a typeless language and probably does not care too much about the meta information. However there are some client frameworks that are wrestling with the issue of java-javascript mapping and doing things like simulating fixed class hierarchies – so maybe the meta information might be important.

Finally there is trmsa – which simply trims the subject area name off the front of property type names. These strings can get a bit long and often they are not needed if you’ve specified the property type name uniquely.

There is some error checking of these arguments, and if any error is encountered a Json error is returned as an “id” and “msg.” There should be no other errors returned.

Json returns values as either numbers or strings, therefore blobs are treated as references and returned as URL’s that reference the specific property, and request the PropertyViewlet do the rendering.

In order to use this viewlet you’ll need to make sure it’s added to the application’s viewlet factory, using something like this:

ret.add(JsonViewlet.choice(realToView, ViewletFactoryChoice.BAD_MATCH_QUALITY));

So please give it a try. It would be nice to build out more components needed to build a rich client experience.

Database Impedance Mismatches

Alex Popescu argues that document databases have an impedance mismatch with object-based software. He compares the situation to relational databases:

“One of the most often mentioned issues reported by software engineers working with relational databases from object-oriented languages is the object-relational impedance mismatch. Document databases adopters are saying that one benefit of document stores is that there is no impedance mismatch between the object and document worlds.

“I don’t think this is entirely true.”

Given that databases and in-memory representations of objects serve different purposes, I don’t think we’ll ever completely manage to do without mappers of some kind. (Otherwise we’d all be using Java Object Serialization as our database.)

However, to me at least it appears that of all database technologies, graph databases like InfoGrid have the smallest impedance mismatch: a graph of objects is fundamentally closer to what is happening in memory of an object-based application than any other representation (e.g. document-based / hierarchical / relational / key-value etc.)

NetBeans7 and Tomcat6

InfoGrid trunk has been upgraded to NetBeans7, but for the time being, we remain with Tomcat6. Unfortunately the NetBeans guys have not exactly made it easy to remain compiling JSPs against the Tomcat6-supported specs instead of Glassfish.

In the relevant InfoGrid projects, we set the relevant properties in project.properties for Tomcat6. They are picked up when running the build from the command line.

If you find yourself with compilation errors when compiling from the IDE, the following trick might help:

  • Find your system-wide NetBeans 7.0 properties default file, e.g. ~/.netbeans/7.0/build.properties
  • In that file, find the properties that start with libs.jsp- such as libs.jsp-compiler.classpath.
  • Comment them all out!

Given the sequence in which NetBeans reads in those property files (system-wide, private project-specific, all project-specific), they might override the correct settings otherwise.

What’s the biggest obstacle to GraphDB adoption?

The recent workshop on Graph Databases in Barcelona sparked an interesting debate among vendors of graph databases about how to accelerate graph database adoption.

I don’t think that debate has been resolved yet. Perhaps this post will help a bit.

Some opinions that I heard were:

  • there are significant differences between the various graph database products on the market (e.g. graphs, property graphs, properties on edges or not, hypergraphs etc.). Unless they are more similar, customers will fear lock-in and not buy any of them. Here is a variation:
  • relational databases only took off once there was agreement on the SQL standard among vendors. We need to cooperate to create a similar language, otherwise graph database adoption will not take off either.
  • most potential users of graph databases have never heard of them. How could they use any if they don’t know they exist?
  • even if possible users know of graph databases, they do not know what the use cases are because use cases and success stories have not broadly been documented.

What do you think the biggest obstacles are for graph database adoption?

Generating a Hierarchical HTML Outline

Graph databases like InfoGrid are much better at traversing recursive data structures than relational databases. That is probably an established fact by now and not controversial.

But what does this mean in practice?

Here is an example just how simple it can be to generate a hierarchical HTML outline from a graph using InfoGrid’s custom tags:

<dl>
  <tree:treeIterate
            startObjectName="Subject"
            traversalSpecification="xpath:*"
            meshObjectLoopVar="current">
    <tree:down>
      <dd><dl>
    </tree:down>
    <tree:up>
      </dl></dd>
    </tree:up>
    <tree:nodeBefore>
      <dt>
        <mesh:meshObject meshObjectName="current"/>
      </dt>
    </tree:nodeBefore>
  </tree:treeIterate>
</dl>

The result is a set of nested HTML definition lists, which are a good match for an outline in HTML.

By way of explanation of this example, the outer tag is a big loop, which iterates over all elements in the outline. Every time we walk down the tree, the <tree:down> tag fires and emits the HTML list start element contained there. Every time we walk up the tree, the corresponding <tree:up> tag triggers and closes the list. “Subject” is the name of the start node as JSP bean, and the xpath-like expression is used to describe which branches to traverse in the graph, because it would just as simple traversing the opposite direction, or sideways.

I don’t think it gets much simpler ;-) Imagine the pain in SQL, particularly if the tree is deep …

Web Apps and InfoGrid

Graph databases are great for web apps: instead of somehow having to map tables and rows to URLs, developers can simply 1-to-1 map objects in the GraphDB to URLs.

Unlike most other GraphDBs, InfoGrid has extensive libraries to make the creation of web pages from dynamic graphs straightforward.

Here’s an example. Let’s say on your web page, you want to show a list of nodes related to some node ‘x’. For example, a social media friends list, or list of purchases, or bookmarks etc. Here is the JSP code:

<set:traverseIterate startObjectName="x" traversalSpecification="*" loopVar="y">
  <set:iterateNoContent><p>Sorry, no neighbors.</p></set:iterateNoContent>
  <set:iterateHeader>
    <ul>
  </set:iterateHeader>
  <set:iterateContentRow>
    <li>
      <mesh:meshObjectLink meshObjectName="y">
        <mesh:meshObject meshObjectName="y" />
      </mesh:meshObjectLink>
    <li>
  </set:iterateContentRow>
  <set:iterateFooter>
    </ul>
  </set:iterateFooter>
<set:traverseIterate>

If you look closely, you see that not only does it print the neighbor nodes in the graph, but also adds a hyperlink to them, so they can clicked on and examined. And if there are no neighbors, a message is printed saying so.

What if I don’t want any kind of neighbor, but only those related in some fashion, say business colleagues? Well, depends a bit on your model, but it’s usually as simple as replacing the first line of JSP above with something like this:

<set:traverseIterate startObjectName="x"
        traversalSpecification="com.example.MySubjectArea/Person_IsColleagueOf_Person-S"
        loopVar="y">

Notice that there is no other code that needs to be written, no object-relational mapping, no SQL syntax to get right, no handler code or other clumsy magic. Of course, you can have may of these statements on the same page, nested etc.

A great way of developing rich web pages really quickly.

The Bless Relationships API

InfoGrid supports types on both nodes and edges, aka MeshObjects and Relationships. They are called EntityTypes and RelationshipsTypes, respectively.

Assume we have two related MeshObjects, each blessed with a (hypothetical) type Person. Like this:

MeshObject obj1 = ...;
MeshObject obj2 = ...;
obj1.bless( PERSON );
obj2.bless( PERSON );
obj1.relate( obj2 );

Now if we want to express that the second Person is the daughter of the first Person, we cannot do this:

obj1.blessRelationship( PERSON_PARENT_PERSON, obj2 );

because we don’t know, from this API, whether obj1 or obj2 is the daughter or the parent.

Instead, in InfoGrid, we have to explicitly specify the direction, and we do this by specifying the “end” of the relationship type instead of the relationship type for the bless operation, like this:

obj1.blessRelationship( PERSON_PARENT_PERSON.getSource(), obj2 );

Hopefully, the documentation of the parent relationship type in the model indicates the semantics of the source and the destination of each relationship type. These “ends” are called RoleTypes, by the way.

One nice side effect of this approach to the API is that it becomes quite straightforward to extend it if InfoGrid ever decided to support ternary or N-ary relationship types: Just pick a RoleType beyond a source or destination RoleType.

If you bless relationships from the HttpShell — the simplest way of manipulating the graph from a web application — you thus need to specify the identifier of the RoleType, not of the RelationshipType. By convention, the source RoleType of a RelationshipType with identifier ID is ID-S, and ID-D for the destination.