1 7 package org.jboss.cache.interceptors; 8 9 import org.jboss.cache.CacheException; 10 import org.jboss.cache.CacheSPI; 11 import org.jboss.cache.Fqn; 12 import org.jboss.cache.GlobalTransaction; 13 import org.jboss.cache.InvocationContext; 14 import org.jboss.cache.NodeSPI; 15 import org.jboss.cache.OptimisticTransactionEntry; 16 import org.jboss.cache.TransactionEntry; 17 import org.jboss.cache.factories.NodeFactory; 18 import org.jboss.cache.marshall.MethodCall; 19 import org.jboss.cache.marshall.MethodDeclarations; 20 import org.jboss.cache.notifications.Notifier; 21 import org.jboss.cache.optimistic.DataVersion; 22 import org.jboss.cache.optimistic.TransactionWorkspace; 23 import org.jboss.cache.optimistic.WorkspaceNode; 24 25 import java.util.ArrayList ; 26 import java.util.List ; 27 28 34 public class OptimisticCreateIfNotExistsInterceptor extends OptimisticInterceptor 35 { 36 private NodeFactory nodeFactory; 37 38 public void setCache(CacheSPI cache) 39 { 40 super.setCache(cache); 41 nodeFactory = cache.getConfiguration().getRuntimeConfig().getNodeFactory(); 42 } 43 44 public Object invoke(MethodCall m) throws Throwable 45 { 46 47 if (MethodDeclarations.isPutMethod(m.getMethodId())) 49 { 50 Object [] args = m.getArgs(); 51 Fqn fqn = (Fqn) (args != null ? args[1] : null); 52 53 if (!cache.getRoot().hasChild(fqn)) 54 { 55 createNode(fqn, false); 56 } 57 } 58 else if (m.getMethodId() == MethodDeclarations.moveMethodLocal_id) 59 { 60 Object [] args = m.getArgs(); 61 move((Fqn) args[0], (Fqn) args[1]); 62 } 63 64 return super.invoke(m); 65 } 66 67 private void move(Fqn nodeFqn, Fqn newParent) 68 { 69 List <Fqn> fqns = new ArrayList <Fqn>(); 70 fqns.add(newParent); 71 72 NodeSPI node = cache.peek(nodeFqn); 74 greedyGetFqns(fqns, node, newParent); 75 76 77 if (log.isTraceEnabled()) log.trace("Adding Fqns to workspace " + fqns); 78 79 80 for (Fqn f : fqns) 81 { 82 if (!cache.getRoot().hasChild(f)) createNode(f, true); 83 } 84 } 85 86 92 private void createNode(Fqn fqn, boolean suppressNotification) throws CacheException 93 { 94 if (fqn == null) return; 96 97 GlobalTransaction gtx = cache.getInvocationContext().getGlobalTransaction(); 99 TransactionEntry baseTransactionEntry = txTable.get(gtx); 100 OptimisticTransactionEntry transactionEntry = (OptimisticTransactionEntry) baseTransactionEntry; 101 102 if (transactionEntry == null) 103 { 104 throw new CacheException("Unable to map global transaction " + gtx + " to transaction entry"); 105 } 106 107 WorkspaceNode workspaceNode, childWorkspaceNode; 108 Object childName; 109 110 List <Fqn> nodesCreated = new ArrayList <Fqn>(); 111 int treeNodeSize = fqn.size(); 113 114 InvocationContext ctx = cache.getInvocationContext(); 115 116 TransactionWorkspace workspace = transactionEntry.getTransactionWorkSpace(); 118 119 boolean debug = log.isDebugEnabled(); 120 synchronized (workspace) 121 { 122 DataVersion version = null; 123 if (ctx.getOptionOverrides() != null && ctx.getOptionOverrides().getDataVersion() != null) 124 { 125 version = ctx.getOptionOverrides().getDataVersion(); 126 workspace.setVersioningImplicit(false); 127 } 128 129 workspaceNode = workspace.getNode(Fqn.ROOT); 130 if (debug) log.debug("Global TX: " + gtx + " Root: " + workspaceNode); 131 132 if (workspaceNode == null) 135 { 136 NodeSPI node = cache.getRoot(); 137 workspaceNode = nodeFactory.createWorkspaceNode(node, workspace); 138 workspace.addNode(workspaceNode); 139 if (debug) log.debug("Created root node: " + workspaceNode); 140 } 141 else 142 { 143 if (debug) log.debug("Found root node: " + workspaceNode); 144 } 145 146 Fqn tmpFqn = Fqn.ROOT; 148 for (int i = 0; i < treeNodeSize; i++) 149 { 150 boolean isTargetFqn = (i == (treeNodeSize - 1)); 151 childName = fqn.get(i); 152 153 tmpFqn = new Fqn(tmpFqn, childName); 155 156 159 if (debug) 160 { 161 log.debug("workspaceNode.getChild(" + childName + ")"); 162 } 163 NodeSPI tempchildNode = workspaceNode.getChild(new Fqn(childName)); 164 165 167 if (tempchildNode == null) 169 { 170 if (debug) log.debug("Creating new child, doesn't exist"); 171 WorkspaceNode tempCheckWrapper = workspace.getNode(workspaceNode.getFqn()); 173 if (tempCheckWrapper == null || tempCheckWrapper.isDeleted()) 174 { 175 if (debug) 177 { 178 log.debug("Parent node doesn't exist in workspace or has been deleted. Adding to workspace."); 179 } 180 workspace.addNode(workspaceNode); 181 } 182 else 183 { 184 if (debug) 185 { 186 log.debug("Parent node exists: " + workspaceNode); 187 } 188 } 189 192 DataVersion versionToPassIn = null; 194 if (isTargetFqn && !workspace.isVersioningImplicit()) 195 { 196 versionToPassIn = version; 197 } 198 199 NodeSPI tempNode = workspaceNode.createChild(childName, workspaceNode.getNode(), cache, versionToPassIn); 200 201 childWorkspaceNode = nodeFactory.createWorkspaceNode(tempNode, workspace); 202 childWorkspaceNode.setVersioningImplicit(versionToPassIn == null || !isTargetFqn); 203 if (log.isTraceEnabled()) 204 { 205 log.trace("setting versioning of " + childWorkspaceNode.getFqn() + " to be " + (childWorkspaceNode.isVersioningImplicit() ? "implicit" : "explicit")); 206 } 207 208 workspace.addNode(childWorkspaceNode); 210 childWorkspaceNode.markAsCreated(); 211 nodesCreated.add(tmpFqn); 214 215 } 216 else 217 { 218 childWorkspaceNode = workspace.getNode(tempchildNode.getFqn()); 220 if (childWorkspaceNode == null || childWorkspaceNode.isDeleted()) 222 { 223 if (debug) 224 { 225 log.debug("Child node " + tempchildNode.getFqn() + " doesn't exist in workspace or has been deleted. Adding to workspace in gtx " + gtx); 226 } 227 childWorkspaceNode = nodeFactory.createWorkspaceNode(tempchildNode, workspace); 228 if (isTargetFqn && !workspace.isVersioningImplicit()) 229 { 230 childWorkspaceNode.setVersion(version); 231 childWorkspaceNode.setVersioningImplicit(false); 232 } 233 else 234 { 235 childWorkspaceNode.setVersioningImplicit(true); 236 } 237 if (log.isTraceEnabled()) 238 { 239 log.trace("setting versioning of " + childWorkspaceNode.getFqn() + " to be " + (childWorkspaceNode.isVersioningImplicit() ? "implicit" : "explicit")); 240 } 241 242 } 243 else 244 { 245 if (debug) 246 { 247 log.debug("Found child node: " + tempchildNode); 248 } 249 250 } 251 } 252 workspaceNode = childWorkspaceNode; 253 } 254 255 } if (debug) log.debug("done synchronized access of GlobalTX"); 257 258 if (!suppressNotification) 259 { 260 if (nodesCreated.size() > 0) 261 { 262 Notifier n = cache.getNotifier(); 263 for (Fqn temp : nodesCreated) 264 { 265 n.notifyNodeCreated(temp, true, false); 266 n.notifyNodeCreated(temp, false, false); 267 if (log.isDebugEnabled()) log.debug("Notifying cache of node created in workspace " + temp); 268 } 269 } 270 } 271 } 272 273 } 274 | Popular Tags |