package org.orienteer.pages.web;
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import org.apache.wicket.MarkupContainer;
import org.apache.wicket.markup.DefaultMarkupCacheKeyProvider;
import org.apache.wicket.markup.DefaultMarkupResourceStreamProvider;
import org.apache.wicket.markup.IMarkupCacheKeyProvider;
import org.apache.wicket.markup.IMarkupResourceStreamProvider;
import org.apache.wicket.markup.MarkupFactory;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.model.CompoundPropertyModel;
import org.apache.wicket.model.IDetachable;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.util.SetModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;
import org.apache.wicket.util.io.IClusterable;
import org.apache.wicket.util.resource.AbstractStringResourceStream;
import org.apache.wicket.util.resource.IFixedLocationResourceStream;
import org.apache.wicket.util.resource.IResourceStream;
import org.apache.wicket.util.resource.StringResourceStream;
import org.apache.wicket.util.string.Strings;
import org.orienteer.core.OrienteerWebSession;
import org.orienteer.pages.OPageParametersEncoder;
import org.orienteer.pages.module.PagesModule;
import com.orientechnologies.common.concur.resource.OPartitionedObjectPool;
import com.orientechnologies.common.log.OLogManager;
import com.orientechnologies.orient.core.Orient;
import com.orientechnologies.orient.core.command.script.OScriptManager;
import com.orientechnologies.orient.core.db.document.ODatabaseDocument;
import com.orientechnologies.orient.core.db.document.ODatabaseDocumentTx;
import com.orientechnologies.orient.core.id.ORID;
import com.orientechnologies.orient.core.id.ORecordId;
import com.orientechnologies.orient.core.record.impl.ODocument;
import com.orientechnologies.orient.core.schedule.OSchedulerListener.SCHEDULER_STATUS;
import ru.ydn.wicket.wicketorientdb.model.ODocumentModel;
import ru.ydn.wicket.wicketorientdb.model.ODocumentPropertyModel;
/**
* Delegate for functions which commonly used in wrapped pages
*/
public class PageDelegate implements IMarkupResourceStreamProvider, IMarkupCacheKeyProvider, IDetachable, IClusterable{
private static final IMarkupResourceStreamProvider DEFAULT_MARKUP_PROVIDER = new DefaultMarkupResourceStreamProvider();
private static final IMarkupCacheKeyProvider DEFAULT_MARKUP_CACHKEY_PROVIDER = new DefaultMarkupCacheKeyProvider();
private static class OPageResourceStream extends AbstractStringResourceStream implements IFixedLocationResourceStream {
private String content;
private String location;
public OPageResourceStream(ODocument page, String wrapTag) {
super("text/html");
content = (String) page.field(PagesModule.OPROPERTY_CONTENT);
if(!Strings.isEmpty(wrapTag)) content = "<"+wrapTag+">"+content+"</"+wrapTag+">";
location="OPage"+page.getIdentity()+"?v"+page.getVersion();
}
@Override
public String locationAsString() {
return location;
}
@Override
protected String getString() {
return content;
}
}
private final WebPage page;
private final ODocumentModel pageDocumentModel;
public PageDelegate(WebPage page, PageParameters parameters) {
this(page, parameters.get(OPageParametersEncoder.PAGE_IDENTITY).toString(), parameters.get("rid").toOptionalString());
}
public PageDelegate(WebPage page, String pageOrid, String docOrid) {
this(page, new ORecordId(pageOrid), Strings.isEmpty(docOrid)?null:new ORecordId(docOrid));
}
public PageDelegate(WebPage page, ORID pageOrid, ORID docOrid) {
this.page = page;
this.pageDocumentModel = new ODocumentModel(pageOrid);
ODocument doc = (ODocument)(docOrid!=null?docOrid.getRecord():pageDocumentModel.getObject().field(PagesModule.OPROPERTY_DOCUMENT));
if(doc!=null) page.setDefaultModel(new ODocumentModel(doc));
String script = pageDocumentModel.getObject().field(PagesModule.OPROPERTY_SCRIPT);
if(!Strings.isEmpty(script)) {
OScriptManager scriptManager = Orient.instance().getScriptManager();
ODatabaseDocument db = OrienteerWebSession.get().getDatabase();
final OPartitionedObjectPool.PoolEntry<ScriptEngine> entry =
scriptManager.acquireDatabaseEngine(db.getName(), "javascript");
final ScriptEngine scriptEngine = entry.object;
Bindings binding = null;
try {
binding = scriptManager.bind(scriptEngine.getBindings(ScriptContext.ENGINE_SCOPE),
(ODatabaseDocumentTx) db, null, null);
binding.put("page", page);
binding.put("pageDoc", pageDocumentModel.getObject());
binding.put("doc", doc);
try {
scriptEngine.eval(script);
} catch (ScriptException e) {
scriptManager.throwErrorMessage(e, script);
}
} finally {
if (scriptManager != null && binding != null) {
scriptManager.unbind(binding, null, null);
scriptManager.releaseDatabaseEngine("javascript", db.getName(), entry);
}
}
}
}
@Override
public void detach() {
pageDocumentModel.detach();
}
public ODocumentModel getPageDocumentModel() {
return pageDocumentModel;
}
@Override
public String getCacheKey(MarkupContainer container, Class<?> containerClass) {
ODocument pageDoc = pageDocumentModel.getObject();
return DEFAULT_MARKUP_CACHKEY_PROVIDER.getCacheKey(container, containerClass)+"_"+pageDoc.getIdentity().toString()+"_v"+pageDoc.getVersion();
}
@Override
public IResourceStream getMarkupResourceStream(MarkupContainer container,
Class<?> containerClass) {
return getMarkupResourceStream(container, containerClass, null);
}
public IResourceStream getMarkupResourceStream(MarkupContainer container,
Class<?> containerClass, String wrapTag) {
if(container.getClass().equals(containerClass)) {
return new OPageResourceStream(pageDocumentModel.getObject(), wrapTag);
} else {
return DEFAULT_MARKUP_PROVIDER.getMarkupResourceStream(container, containerClass);
}
}
public IModel<String> getTitleModel() {
return new ODocumentPropertyModel<String>(pageDocumentModel, "title");
}
}