package org.sitemesh.content.tagrules.html;
import java.io.File;
import java.nio.file.Paths;
import java.nio.CharBuffer;
import org.sitemesh.SiteMeshContext;
import org.sitemesh.content.memory.InMemoryContent;
import org.sitemesh.content.ContentProperty;
import org.sitemesh.content.Content;
import org.sitemesh.tagprocessor.Tag;
import org.sitemesh.tagprocessor.BasicBlockRule;
import org.sitemesh.offline.directory.Directory;
import org.sitemesh.offline.directory.FileSystemDirectory;
import java.io.IOException;
/**
* Rule that applies decorators to an external file and insert decorated content in the current page
*
*
* <h3>Example</h3>
*
* {@code <sitemesh:decorate decorator='/mydecorator' srcfile='/fragment.html'/>}
*
* <p>This will apply the decorator named <code>/mydecorator</code>, on the file <code>fragment.html</code>
* and insert the result in the current page</p>
*
* @author Fabrice Gaillard
*/
public class SiteMeshIncludeRule extends BasicBlockRule<SiteMeshIncludeRule.Holder> {
static class Holder {
public final Content content = new InMemoryContent();
public String decoratorName;
}
private final SiteMeshContext siteMeshContext;
public SiteMeshIncludeRule(SiteMeshContext siteMeshContext) {
this.siteMeshContext = siteMeshContext;
}
@Override
protected Holder processStart(Tag tag) throws IOException {
tagProcessorContext.pushBuffer();
Holder holder = new Holder();
for (int i = 0, count = tag.getAttributeCount(); i < count; i++) {
String name = tag.getAttributeName(i);
String value = tag.getAttributeValue(i);
if (name.equals("decorator")) {
holder.decoratorName = value;
}
if (name.equals("srcfile")) {
//
// try to incude the file referenced in srcfile
// we need to figure the path, relative to the current dir
//
//String curpage = siteMeshContext.getPath();
String curpath = Paths.get("").toAbsolutePath().toString();
Directory curdir = new FileSystemDirectory(new File(curpath));
CharBuffer input = curdir.load(value);
//
// works, but it seems the content is not processed (body not extracted)
//
holder.content.getData().setValue(input);
holder.content.getExtractedProperties().getChild("body").setValue(input);
}
}
return holder;
}
@Override
protected void processEnd(Tag tag, Holder holder) throws IOException {
CharSequence defaultContents = tagProcessorContext.currentBufferContents();
tagProcessorContext.popBuffer();
Content decorated = siteMeshContext.decorate(holder.decoratorName, holder.content);
if (decorated != null) {
// TODO: Use a 'default' property
decorated.getExtractedProperties().getChild("body").writeValueTo(tagProcessorContext.currentBuffer());
}
}
}