1 13 package info.magnolia.commands; 14 15 import info.magnolia.cms.util.AlertUtil; 16 17 import java.util.Collections ; 18 import java.util.Map ; 19 20 import org.apache.commons.beanutils.BeanUtils; 21 import org.apache.commons.chain.Command; 22 import org.apache.commons.chain.Context; 23 import org.apache.commons.lang.exception.NestableException; 24 import org.apache.commons.pool.BasePoolableObjectFactory; 25 import org.apache.commons.pool.impl.StackObjectPool; 26 27 28 35 public abstract class MgnlCommand implements Command { 36 37 40 private Map defaultProperties; 41 42 private boolean isClone = false; 43 44 49 class MgnlCommandFactory extends BasePoolableObjectFactory { 50 51 54 private MgnlCommand prototype; 55 56 59 public MgnlCommandFactory(MgnlCommand prototype) { 60 this.prototype = prototype; 61 } 62 63 public Object makeObject() throws Exception { 64 MgnlCommand cmd = (MgnlCommand) BeanUtils.cloneBean(this.prototype); 65 cmd.setClone(true); 66 return cmd; 67 } 68 69 public void activateObject(Object arg0) throws Exception { 70 super.activateObject(arg0); 71 BeanUtils.populate(arg0, defaultProperties); 73 } 74 75 public void passivateObject(Object cmd) throws Exception { 76 ((MgnlCommand) cmd).release(); 77 super.passivateObject(cmd); 78 } 79 80 } 81 82 85 private StackObjectPool pool; 86 87 90 private boolean pooling = true; 91 92 95 public boolean execute(Context ctx) throws Exception { 96 if (!(ctx instanceof info.magnolia.context.Context)) { 97 throw new IllegalArgumentException ("context must be of type " + info.magnolia.context.Context.class); 98 } 99 100 if (this.defaultProperties == null) { 101 initDefaultProperties(); 102 } 103 104 MgnlCommand cmd; 105 106 if (pooling) { 107 if (pool == null) { 110 pool = new StackObjectPool(new MgnlCommandFactory(this)); 111 } 112 113 try { 114 cmd = (MgnlCommand) pool.borrowObject(); 116 } 117 catch (InstantiationException e) { 119 pooling = false; 120 return execute(ctx); 122 } 123 } 124 else { 125 cmd = this; 126 } 127 128 boolean success = executePooledOrSynchronized(ctx, cmd); 129 return !success; 131 } 132 133 private boolean executePooledOrSynchronized(Context ctx, MgnlCommand cmd) throws Exception { 134 boolean success = false; 136 if (pooling) { 138 BeanUtils.populate(cmd, ctx); 139 try { 141 success = cmd.execute((info.magnolia.context.Context) ctx); 142 } 143 catch (Exception e) { 144 AlertUtil.setException(e, (info.magnolia.context.Context) ctx); 145 throw new NestableException("exception during executing command", e); 146 } 147 finally { 148 pool.returnObject(cmd); 149 } 150 } 151 else { 152 synchronized (cmd) { 153 BeanUtils.populate(cmd, ctx); 154 try { 155 success = cmd.execute((info.magnolia.context.Context) ctx); 156 } 157 catch (Exception e) { 158 AlertUtil.setException(e, (info.magnolia.context.Context) ctx); 159 throw new NestableException("exception during executing command", e); 160 } 161 finally { 162 if (pooling) { 163 pool.returnObject(cmd); 164 } 165 else { 166 cmd.release(); 167 BeanUtils.populate(cmd, defaultProperties); 168 } 169 } 170 } 171 } 172 return success; 173 } 174 175 private void initDefaultProperties() { 176 try { 177 this.defaultProperties = BeanUtils.describe(this); 178 } 179 catch (Exception e) { 180 this.defaultProperties = Collections.EMPTY_MAP; 181 } 182 } 183 184 public abstract boolean execute(info.magnolia.context.Context context) throws Exception ; 185 186 189 public void release() { 190 } 191 192 195 protected boolean isClone() { 196 return isClone; 197 } 198 199 202 protected void setClone(boolean isClone) { 203 this.isClone = isClone; 204 } 205 206 } 207 | Popular Tags |