Refactor artifacts into more general types such as SimpleFileArtifact, along with a multi-aspect AspectualArtifact, a type of CompositeArtifact.
When implementing GUISE-112, the conceptualization of what an "artifact" is evolved. They are now best understood as semantic placeholders in the site plan (). Artifacts are meant:
To indicate the resource place in the artifact tree.
To provide a metadata description of the resource.
To indicate any tree-related attributes (e.g. navigability).
To indicate any child artifacts.
To indicate the source of the content (the file and/or any alternate input stream) for mummification.
To indicate the destination of the content.
Artifacts thus give a sort of logical tree of the produced resources, although they might not correspond directly to the tree of resource paths (e.g. child post artifacts actually produce multiple sub-collection paths). Each artifact would be mostly agnostic to any particular type of content passing through it; this would be handled by its associated mummifier. The artifact would be sort of a coordination point.
Thus there seems to be no purpose for the PageArtifact other than to indicate that it is a navigable artifact—something that could be done with any general artifact. That is, there is currently no use in semantically marking the artifact as a "page". (In fact if we were to need such a marker, it should be noted that DefaultXhtmlPhantomArtifact technically should be marked as a "page" as well—it currently is not.) In fact OpaqueFileArtifact is currently implemented no differently than a PageArtifact, except that it is marked not navigable.
Thus we can replace PageArtifact, PostArtifact, OpaqueFileArtifact with a SimpleFileArtifact that allows specification of whether it is navigable and whether it is a post.
In addition we need a type of composite artifact that can offer several "aspects", or predefined views of the artifact. The archetypal aspectual artifact is an image artifact, which will have () a "preview" aspect that is smaller (and potentially even an even smaller "thumbnail" aspect). As discussed in GUISE-178, the term "aspect" here (which is from the Latin aspectus: "to look at") is a middle ground between "facet", which has more of a sense of "part of a whole"; and "perspective, which is more subjective and depends on how it is being viewed by the viewer. Thus "aspect" means some intrinsic, predefined way of looking at the resource.
Create an interface AspectualArtifact that extends CompositeArtifact to allow processing of its contained aspect artifact, each of type AspectArtifact. The AspectualArtifact will allow lookup of its aspects by some aspect ID such as preview, and each AspectArtifact will allow its aspect ID to be retrieved.
A fly in the ointment of generalized artifact types is the PostArtifact of GUISE-108. It seems to be used only for two things:
Determining whether a post date-based path should be generated based on the filename. This doesn't pose a problem with generalization, as we can put the pattern definitions elsewhere, e.g. in some Posts class that isn't necessarily a special type of Artifact.
Filtering posts out when determining default navigation in AbstractPageMummifierdefaultNavigationArtifacts(…). Even here there is a comment: "TODO create a more semantic means of filtering posts". Haven't a special Post class to indicate a post didn't feel right even then.
Why were posts filtered to begin with? Was it just to keep a blog home page from being overloaded with a bunch of children? Maybe the logic went like this: "Multi-level path generation based on date is usually done for blog posts, and when we have blog posts there could be a lot of them, so we'll assume that if something generated date-based path structure we won't include them in navigation as a pragmatic choice." But filtering "posts" from navigation lists (or even assuming a generated date-base path is a "post") probably isn't getting to the heart of the issue semantically—hence the TODO comment.
Because the path was generated based upon the date, let's go ahead and call them "posts" because they were "posted" on this date. We can move the filename patterns to Artifact or even have it be configurable at some point. We don't need a separate artifact type for them. We can just have a general flag Artifact.isPost(), because after all even images can have post paths generated.
We will now have various flags to deal with. A compelling idea is to have an Artifact.builder() that allows us to specify whether an artifact is navigable, is a post, has aspects, etc. The builder would create the appropriate type of artifact. But I want to think about that some more. For the moment we can just have a SimpleFileArtifact and a AspectualFileArtifact.
For posts, I believe that the artifact itself can determine whether it is a post by looking at its own source path when it is created—no need for the mummifier to do this. This means even non-pages (e.g. images) will be recognized as posts if appropriate, and "post" and "navigable" truly become orthogonal.
For actual aspect artifacts, I'm deciding how to indicate that the artifact is an aspect and what aspect it is. One option would be to add something like an Artifact.findAspect() to every artifact, but I'm worried about making the Artifact interface turn into a grab-bag of various options. Is the concept of an "artifact" sufficiently central to the model to be promoted to the Artifact interface?
And what about the artifact resource description? Should we instead just add a mummy/aspect property to the description? That would provide an extra benefit: it would allow users to arbitrarily turn any e.g. image into a preview just by adding mummy/aspect="preview" to the description (when we support general metadata sidecar files, for example).
The underlying JEXL implementation of MEXL currently doesn't support simply foo.bar('foobar') as an expression if the Foo method is getBar(String), so let's rename AspectualArtifact.getAspect(String) to just AspectualArtifact.aspect(String) for now to make the MEXL expressions more concise and fluent.