001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.test.jmx.interceptors;
023:
024: import java.io.File;
025: import java.io.FileOutputStream;
026: import java.io.IOException;
027: import java.io.ObjectOutputStream;
028: import java.io.FileInputStream;
029: import java.io.ObjectInputStream;
030: import java.lang.reflect.Method;
031:
032: import javax.naming.Name;
033: import javax.naming.NameNotFoundException;
034: import javax.management.MBeanException;
035: import javax.management.ReflectionException;
036:
037: import org.jboss.mx.interceptor.AbstractInterceptor;
038: import org.jboss.mx.interceptor.Interceptor;
039: import org.jboss.mx.server.Invocation;
040: import org.jboss.logging.Logger;
041:
042: /** A simple file based persistence interceptor that saves the value of
043: * Naming.bind() calls as serialized objects.
044: *
045: * @author Scott.Stark@jboss.org
046: * @version $Revision: 57211 $
047: */
048: public final class JNDIPersistence extends AbstractInterceptor {
049: private static Logger log = Logger.getLogger(JNDIPersistence.class);
050:
051: private File storeDirectory;
052:
053: public File getStoreDirectory() {
054: return storeDirectory;
055: }
056:
057: public void setStoreDirectory(File storeDirectory) {
058: log.info("setStoreDirectory: " + storeDirectory);
059: if (storeDirectory.exists() == false)
060: storeDirectory.mkdir();
061: this .storeDirectory = storeDirectory;
062: }
063:
064: // Interceptor overrides -----------------------------------------
065: public Object invoke(Invocation invocation) throws Throwable {
066: String opName = invocation.getName();
067: log.info("invoke, opName=" + opName);
068:
069: // If this is not the invoke(Invocation) op just pass it along
070: if (opName == null || opName.equals("invoke") == false) {
071: Interceptor i = invocation.nextInterceptor();
072: return i.invoke(invocation);
073: }
074:
075: Object[] args = invocation.getArgs();
076: org.jboss.invocation.Invocation invokeInfo = (org.jboss.invocation.Invocation) args[0];
077:
078: Object[] iargs = invokeInfo.getArguments();
079: for (int a = 0; a < args.length; a++)
080: log.info(" args[" + a + "]=" + iargs[a]);
081: Method method = invokeInfo.getMethod();
082: String methodName = method.getName();
083: log.info("methodName: " + methodName);
084: Object value = null;
085: if (methodName.equals("bind")) {
086: log.info("Dispatching bind");
087: invocation.nextInterceptor().invoke(invocation);
088: // Bind succeeded, save the value
089: log.info("Saving bind data");
090: Name name = (Name) iargs[0];
091: Object data = iargs[1];
092: try {
093: writeBinding(name, data);
094: } catch (Throwable e) {
095: log.error("Failed to write binding", e);
096: throw e;
097: }
098: } else if (methodName.equals("lookup")) {
099: log.info("Dispatching lookup");
100: try {
101: value = invocation.nextInterceptor().invoke(invocation);
102: log.info("lookup returned: " + value);
103: } catch (Throwable ex) {
104: ex = getException(ex);
105: log.info("InvocationException: ", ex);
106: if (ex instanceof NameNotFoundException) {
107: log
108: .info("NameNotFoundException in lookup, finding data");
109: Name name = (Name) iargs[0];
110: try {
111: value = readBinding(name);
112: if (value == null)
113: throw ex;
114: } catch (Throwable e2) {
115: log.error("Failed to read binding", e2);
116: throw e2;
117: }
118: }
119: }
120: } else {
121: value = invocation.nextInterceptor().invoke(invocation);
122: }
123:
124: return value;
125: }
126:
127: private void writeBinding(Name name, Object data)
128: throws IOException {
129: File dataFile = new File(storeDirectory, name.toString());
130: FileOutputStream fos = new FileOutputStream(dataFile);
131: ObjectOutputStream oos = new ObjectOutputStream(fos);
132: oos.writeObject(data);
133: oos.close();
134: fos.close();
135: log.info("Wrote data binding to: " + dataFile);
136: }
137:
138: private Object readBinding(Name name) throws IOException,
139: ClassNotFoundException {
140: File dataFile = new File(storeDirectory, name.toString());
141: if (dataFile.exists() == false)
142: return null;
143:
144: FileInputStream fis = new FileInputStream(dataFile);
145: ObjectInputStream ois = new ObjectInputStream(fis);
146: Object data = ois.readObject();
147: ois.close();
148: fis.close();
149: log.info("Read data binding from: " + dataFile);
150: return data;
151: }
152:
153: /** Unwrap the InvocationException to see what the Naming service
154: * exception really was.
155: *
156: * @param ex the wrapped InvocationException
157: * @return the underlying initial exception
158: */
159: Throwable getException(Throwable ex) {
160: if (ex instanceof MBeanException) {
161: MBeanException mbe = (MBeanException) ex;
162: ex = mbe.getTargetException();
163: } else if (ex instanceof ReflectionException) {
164: ReflectionException re = (ReflectionException) ex;
165: ex = re.getTargetException();
166: }
167: return ex;
168: }
169: }
|