package net.ion.craken.node; import java.io.IOException; import java.util.List; import java.util.Map; import java.util.Set; import net.ion.craken.listener.CDDMListener; import net.ion.craken.node.crud.ChildQueryRequest; import net.ion.craken.node.crud.WriteNodeImpl.Touch; import net.ion.craken.node.crud.tree.Fqn; import net.ion.framework.util.ListUtil; import net.ion.framework.util.MapUtil; import net.ion.framework.util.SetUtil; import net.ion.framework.util.StringUtil; import org.apache.commons.collections.set.ListOrderedSet; import org.apache.lucene.queryparser.classic.ParseException; public abstract class AbstractWriteSession implements WriteSession { private ReadSession rsession; private IndexWriteConfig iwconfig = new IndexWriteConfig(); private Set<TouchedRow> touchedRows = ListOrderedSet.decorate(ListUtil.newList()); private String tranId; private Set<Fqn> ancestorsFqn = SetUtil.newSet(); private Mode mode = Mode.NORMAL; private Map<String, Object> attrs = MapUtil.newMap() ; private enum Mode { NORMAL, RESTORE, OVERWRITE } protected AbstractWriteSession(ReadSession rsession, Workspace workspace) { this.rsession = rsession; } public WriteNode createBy(String fqn) { return createBy(Fqn.fromString(fqn)); } public WriteNode createBy(Fqn fqn) { return workspace().createNode(this, ancestorsFqn, fqn); } public WriteNode resetBy(String fqn) { return resetBy(Fqn.fromString(fqn)); } public WriteNode resetBy(Fqn fqn) { return workspace().resetNode(this, ancestorsFqn, fqn); } public WriteNode pathBy(String fqn) { return pathBy(Fqn.fromString(fqn)); } public WriteNode pathBy(String fqn0, Object... fqns) { return pathBy(Fqn.fromString((fqn0.startsWith("/") ? fqn0 : "/" + fqn0) + '/' + StringUtil.join(fqns, '/'))); } public WriteNode pathBy(Fqn fqn) { return workspace().writeNode(this, ancestorsFqn, fqn); } public WriteNode root() { return pathBy("/"); } public boolean exists(String fqn) { return workspace().exists(Fqn.fromString(fqn)); } public boolean exists(Fqn fqn) { return workspace().exists(fqn); } @Override public void prepareCommit() throws IOException { } public void restore() { this.mode = Mode.RESTORE; } public void restoreOverwrite() { this.mode = Mode.OVERWRITE; } public WriteSession attribute(Class clz, Object value){ attrs.put(clz.getCanonicalName(), value) ; return this ; } public <T> T attribute(Class<T> clz){ return clz.cast(attrs.get(clz.getCanonicalName())) ; } public List<TouchedRow> touched(Touch touch){ List<TouchedRow> result = ListUtil.newList() ; for (TouchedRow row : touchedRows) { if (row.touch() == touch){ result.add(row) ; } } return result ; } public Set<TouchedRow> touchedRows(){ return touchedRows ; } @Override public void endCommit() throws IOException { CDDMListener cddm = attribute(CDDMListener.class) ; TransactionJob tjob = attribute(TransactionJob.class) ; TranExceptionHandler ehandler = attribute(TranExceptionHandler.class) ; NodeWriter nodeWriter = rsession.workspace().createNodeWriter(this, rsession); cddm.fireRow(this, tjob, ehandler); nodeWriter.writeLog(touchedRows) ; touchedRows = ListOrderedSet.decorate(ListUtil.newList()); } @Override public void failRollback() { } @Override public void notifyTouch(WriteNode source, Fqn targetFqn, Touch touch, Map<String, Fqn> affected) { if ((touch == Touch.TOUCH) || (targetFqn.isRoot() && touch == Touch.TOUCH)) return; TouchedRow trow = TouchedRow.create(source, touch, targetFqn, affected); if (touch == Touch.REMOVECHILDREN){ Set<TouchedRow> forRemove = SetUtil.newSet() ; for(TouchedRow row : touchedRows){ if (row.target().isChildOrEquals(targetFqn)){ forRemove.add(row) ; } } touchedRows.removeAll(forRemove) ; } touchedRows.add(trow); } public IndexWriteConfig iwconfig() { return iwconfig; } @Override public Credential credential() { return rsession.credential(); } public ReadSession readSession() { return rsession; } public Workspace workspace() { return rsession.workspace(); } public void continueUnit() throws IOException { workspace().continueUnit(this); } public WriteSession iwconfig(IndexWriteConfig iwconfig) { this.iwconfig = iwconfig; return this; } @Override public ChildQueryRequest queryRequest(String query) throws IOException, ParseException { return root().childQuery(query, true); } }