package ru.ydn.wicket.wicketorientdb;

import org.apache.wicket.request.IRequestHandler;
import org.apache.wicket.request.cycle.IRequestCycleListener;
import org.apache.wicket.request.cycle.RequestCycle;
import org.apache.wicket.request.handler.resource.ResourceReferenceRequestHandler;
import org.apache.wicket.request.resource.PackageResourceReference;
import org.apache.wicket.request.resource.ResourceReference;
import org.apache.wicket.util.lang.Objects;

import com.orientechnologies.orient.core.db.ODatabaseDocumentInternal;
import com.orientechnologies.orient.core.db.ODatabaseRecordThreadLocal;
import com.orientechnologies.orient.core.db.document.ODatabaseDocument;
import com.orientechnologies.orient.core.metadata.security.OSecurityUser;
import com.orientechnologies.orient.core.metadata.security.OUser;

/**
 * Implementation of {@link IRequestCycleListener} for starting and stoping transactions just for pages and dynamic resources
 */
public class TransactionRequestCycleListener extends
		AbstractContentAwareTransactionRequestCycleListener {
	@Override
	public void start(RequestCycle cycle) {
		OrientDbWebSession session = OrientDbWebSession.get();
		ODatabaseDocumentInternal db = session.getDatabase();
		//It's required to have ability to check security rights locally
		OSecurityUser oUser = session.getUser();
		OSecurityUser dbUser = db.getUser();
		if(oUser!=null && oUser.getDocument()!=null 
				&& oUser.getDocument().getIdentity()!=null 
				&& (!oUser.getDocument().getIdentity().isValid() || dbUser==null || !Objects.equal(dbUser.getName(), oUser.getName())))
		{
			db.setUser(db.getMetadata().getSecurity().getUser(oUser.getName()));
		}
		db.begin();
	}
	

	@Override
	public void end(RequestCycle cycle) {
		ODatabaseDocument db = ODatabaseRecordThreadLocal.INSTANCE.get();
		if(db.getTransaction().isActive()) db.commit();
	}
	
	@Override
	public void onDetach(RequestCycle cycle) {
		ODatabaseDocument db = ODatabaseRecordThreadLocal.INSTANCE.get();
		if(db.getTransaction().isActive()) db.commit(true);
		db.close();
		ODatabaseRecordThreadLocal.INSTANCE.remove();
	}
	
	

	@Override
	public IRequestHandler onException(RequestCycle cycle, Exception ex) {
		ODatabaseDocument db = ODatabaseRecordThreadLocal.INSTANCE.get();
		if(!db.isClosed()) db.rollback();
		return null;
	}
	

	@Override
	public boolean isOurContent(RequestCycle cycle, IRequestHandler handler) {
		if(handler instanceof ResourceReferenceRequestHandler)
		{
			ResourceReferenceRequestHandler rrrHandler = (ResourceReferenceRequestHandler)handler;
			ResourceReference reference = rrrHandler.getResourceReference();
			return !(reference instanceof PackageResourceReference);
		}
		return true;
	}

}

@@ -1796,33 +1796,54 @@
 INSTANCE.get
-();%0A%09%09if(
+IfDefined();%0A%09%09if(db!=null && 
 db.getTransa
@@ -1995,28 +1995,55 @@
 INSTANCE.get
+IfDefined
 ();%0A
+%09%09if(db!=null) %7B%0A%09
 %09%09if(db.getT
@@ -2086,16 +2086,17 @@
 rue);%0A%09%09
+%09
 db.close
@@ -2095,24 +2095,25 @@
 db.close();%0A
+%09
 %09%09ODatabaseR
@@ -2144,24 +2144,28 @@
 E.remove();%0A
+%09%09%7D%0A
 %09%7D%0A%09%0A%09%0A%0A%09@Ov
@@ -2307,25 +2307,46 @@
 ANCE.get
-();%0A%09%09if(
+IfDefined();%0A%09%09if(db!=null && 
 !db.isCl

Make finishing transactions more safe if no DB was obtained