You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2007/05/22 12:26:34 UTC
svn commit: r540521 [2/3] - in /jackrabbit/trunk/contrib/jcrlog: ./ src/
src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/jackrabbit/
src/main/java/org/apache/jackrabbit/jcrlog/ src/main/java/org/apache/jac...
Added: jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/RepositoryLogger.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/RepositoryLogger.java?view=auto&rev=540521
==============================================================================
--- jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/RepositoryLogger.java (added)
+++ jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/RepositoryLogger.java Tue May 22 03:26:30 2007
@@ -0,0 +1,240 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.jcrlog;
+
+import java.util.Properties;
+
+import javax.jcr.Credentials;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.jackrabbit.core.TransientRepository;
+
+/**
+ * The public Repository object of the wrapper. Actually does not need to be
+ * used directly by the application (if the RepositoryFactory is used).
+ *
+ * @author Thomas Mueller
+ *
+ */
+public class RepositoryLogger extends LogObject implements Repository {
+
+ private Repository repository;
+
+ /**
+ * Open a repository and wrap it using the RepositoryLogger wrapper.
+ *
+ * @param url the URL
+ * @return the wrapped repository
+ * @throws RepositoryException
+ */
+ public static Repository open(String url) throws RepositoryException {
+ String wrappedURL;
+ int idx = url.toLowerCase().indexOf("url=");
+ if (idx < 0) {
+ wrappedURL = "apache/jackrabbit/transient";
+ } else {
+ wrappedURL = url.substring(idx + "url=".length());
+ url = url.substring(0, idx);
+ }
+ if (url == null || url.length() == 0) {
+ url = "sysout=true";
+ }
+ Properties prop = parseSettings(url);
+ Repository rep = RepositoryFactory.open(wrappedURL);
+ return new RepositoryLogger(rep, prop, wrappedURL);
+ }
+
+ /**
+ * Wrap a repository.
+ *
+ * @param repository
+ * @param settings the settings to use
+ * @return the wrapped repository
+ * @throws RepositoryException
+ */
+ public static Repository wrap(Repository repository, String settings)
+ throws RepositoryException {
+ String url;
+ if (repository instanceof TransientRepository) {
+ url = "apache/jackrabbit/transient";
+ } else {
+ // TODO support other repositories
+ url = "<unknown url, class: " + repository.getClass().getName()
+ + ">";
+ }
+ if (settings == null || settings.length() == 0) {
+ settings = "sysout=true";
+ }
+ Properties prop = parseSettings(settings);
+ return new RepositoryLogger(repository, prop, url);
+ }
+
+ private RepositoryLogger(Repository repository, Properties prop, String url)
+ throws RepositoryException {
+ this.repository = repository;
+ String fileName = prop.getProperty("file");
+ String sysOut = prop.getProperty("sysout");
+ String logReturn = prop.getProperty("return");
+ String logCaller = prop.getProperty("caller");
+ String cast = prop.getProperty("cast");
+ String stream = prop.getProperty("stream");
+ Log log = new Log(fileName, parseBoolean(sysOut));
+ log.setLogCaller(parseBoolean(logCaller));
+ log.setLogReturn(parseBoolean(logReturn));
+ log.setCastToRealApi(parseBoolean(cast));
+ log.setLogStream(parseBoolean(stream));
+ String call = RepositoryFactory.CLASSNAME + ".open("
+ + StringUtils.quoteString(url) + ");";
+ int nextId = getNextId(LogObject.INTERFACE_DEF_REPOSITORY.type);
+ setLog(log, LogObject.INTERFACE_DEF_REPOSITORY.type, nextId);
+ logStartCall(getAssign(LogObject.INTERFACE_DEF_REPOSITORY.type, nextId, call));
+ }
+
+ private boolean parseBoolean(String s) {
+ return Boolean.valueOf(s).booleanValue();
+ }
+
+ private static Properties parseSettings(String settings)
+ throws RepositoryException {
+ Properties prop = new Properties();
+ String[] list = StringUtils.arraySplit(settings, ';');
+ for (int i = 0; list != null && i < list.length; i++) {
+ String setting = list[i];
+ if (setting.length() == 0) {
+ continue;
+ }
+ int equal = setting.indexOf('=');
+ if (equal < 0) {
+ throw new RepositoryException("Invalid settings format: "
+ + settings);
+ }
+ String value = setting.substring(equal + 1).trim();
+ String key = setting.substring(0, equal).trim();
+ key = key.toLowerCase();
+ String old = prop.getProperty(key);
+ if (old != null && !old.equals(value)) {
+ throw new RepositoryException("Duplicate settings: " + key);
+ }
+ prop.setProperty(key, value);
+ }
+ return prop;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getDescriptor(String key) {
+ try {
+ logStart(-1, false, "getDescriptor", StringUtils.quoteString(key));
+ String result = repository.getDescriptor(key);
+ logReturn(String.class, result);
+ return result;
+ } catch (Throwable t) {
+ throw logRuntimeException(t);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String[] getDescriptorKeys() {
+ try {
+ logStart(-1, false, "getDescriptorKeys", "");
+ String[] result = repository.getDescriptorKeys();
+ logReturn(String[].class, result);
+ return result;
+ } catch (Throwable t) {
+ throw logRuntimeException(t);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Session login() throws RepositoryException {
+ try {
+ int assignType = LogObject.INTERFACE_DEF_SESSION.type;
+ int nextId = logStart(assignType, false, "login", "");
+ Session result = repository.login();
+ result = (Session) wrap(result, false, Session.class, assignType,
+ nextId);
+ logReturn();
+ return result;
+ } catch (Throwable t) {
+ throw logAndConvert(t);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Session login(Credentials credentials) throws RepositoryException {
+ try {
+ int assignType = LogObject.INTERFACE_DEF_SESSION.type;
+ int nextId = logStart(assignType, false, "login", StringUtils
+ .quoteCredentials(credentials));
+ Session result = repository.login(credentials);
+ result = (Session) wrap(result, false, Session.class, assignType,
+ nextId);
+ logReturn();
+ return result;
+ } catch (Throwable t) {
+ throw logAndConvert(t);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Session login(String workspaceName) throws RepositoryException {
+ try {
+ int assignType = LogObject.INTERFACE_DEF_SESSION.type;
+ int nextId = logStart(assignType, false, "login", StringUtils
+ .quoteString(workspaceName));
+ Session result = repository.login(workspaceName);
+ result = (Session) wrap(result, false, Session.class, assignType,
+ nextId);
+ logReturn();
+ return result;
+ } catch (Throwable t) {
+ throw logAndConvert(t);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Session login(Credentials credentials, String workspaceName)
+ throws RepositoryException {
+ try {
+ int assignType = LogObject.INTERFACE_DEF_SESSION.type;
+ int nextId = logStart(assignType, false, "login", StringUtils
+ .quoteCredentials(credentials)
+ + ", " + StringUtils.quoteString(workspaceName));
+ Session result = repository.login(credentials, workspaceName);
+ result = (Session) wrap(result, false, Session.class, assignType,
+ nextId);
+ logReturn();
+ return result;
+ } catch (Throwable t) {
+ throw logAndConvert(t);
+ }
+ }
+
+}
Propchange: jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/RepositoryLogger.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/StringUtils.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/StringUtils.java?view=auto&rev=540521
==============================================================================
--- jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/StringUtils.java (added)
+++ jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/StringUtils.java Tue May 22 03:26:30 2007
@@ -0,0 +1,533 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.jcrlog;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Proxy;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+
+import javax.jcr.Credentials;
+import javax.jcr.ItemVisitor;
+import javax.jcr.SimpleCredentials;
+import javax.jcr.observation.EventListener;
+
+/**
+ * Some String manipulations / formatting functions used by this tool.
+ *
+ * @author Thomas Mueller
+ *
+ */
+public class StringUtils {
+
+ private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(
+ "yyyy-MM-dd HH:mm:ss.SSS Z");
+
+ static String[] arraySplit(String s, char separatorChar) {
+ if (s == null) {
+ return null;
+ }
+ if (s.length() == 0) {
+ return new String[0];
+ }
+ ArrayList list = new ArrayList();
+ StringBuffer buff = new StringBuffer(s.length());
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ if (c == separatorChar) {
+ list.add(buff.toString());
+ buff.setLength(0);
+ } else if (c == '\\' && i < s.length() - 1) {
+ buff.append(s.charAt(++i));
+ } else {
+ buff.append(c);
+ }
+ }
+ list.add(buff.toString());
+ String[] array = new String[list.size()];
+ list.toArray(array);
+ return array;
+ }
+
+ private static String addAsterix(String s, int index) {
+ if (s != null && index < s.length()) {
+ s = s.substring(0, index) + "[*]" + s.substring(index);
+ }
+ return s;
+ }
+
+ private static IllegalArgumentException getFormatException(String s, int i) {
+ return new IllegalArgumentException("String format error: "
+ + addAsterix(s, i));
+ }
+
+ /**
+ * Parse a a Java string.
+ *
+ * @param s the string formatted as a Java string
+ * @return the parsed string
+ */
+ public static String javaDecode(String s) {
+ StringBuffer buff = new StringBuffer(s.length());
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ if (c == '"') {
+ break;
+ } else if (c == '\\') {
+ if (i >= s.length()) {
+ throw getFormatException(s, s.length() - 1);
+ }
+ c = s.charAt(++i);
+ switch (c) {
+ case 't':
+ buff.append('\t');
+ break;
+ case 'r':
+ buff.append('\r');
+ break;
+ case 'n':
+ buff.append('\n');
+ break;
+ case 'b':
+ buff.append('\b');
+ break;
+ case 'f':
+ buff.append('\f');
+ break;
+ case '"':
+ buff.append('"');
+ break;
+ case '\\':
+ buff.append('\\');
+ break;
+ case 'u': {
+ try {
+ c = (char) (Integer.parseInt(s.substring(i + 1, i + 5),
+ 16));
+ } catch (NumberFormatException e) {
+ throw getFormatException(s, i);
+ }
+ i += 4;
+ buff.append(c);
+ break;
+ }
+ default:
+ if (c >= '0' && c <= '9') {
+ try {
+ c = (char) (Integer.parseInt(s.substring(i, i + 3),
+ 8));
+ } catch (NumberFormatException e) {
+ throw getFormatException(s, i);
+ }
+ i += 2;
+ buff.append(c);
+ } else {
+ throw getFormatException(s, i);
+ }
+ }
+ } else {
+ buff.append(c);
+ }
+ }
+ return buff.toString();
+ }
+
+ private static String javaEncode(String s) {
+ StringBuffer buff = new StringBuffer(s.length());
+ for (int i = 0; i < s.length(); i++) {
+ char c = s.charAt(i);
+ switch (c) {
+ // case '\b':
+ // // BS backspace
+ // // not supported in properties files
+ // buff.append("\\b");
+ // break;
+ case '\t':
+ // HT horizontal tab
+ buff.append("\\t");
+ break;
+ case '\n':
+ // LF linefeed
+ buff.append("\\n");
+ break;
+ case '\f':
+ // FF form feed
+ buff.append("\\f");
+ break;
+ case '\r':
+ // CR carriage return
+ buff.append("\\r");
+ break;
+ case '"':
+ // double quote
+ buff.append("\\\"");
+ break;
+ case '\\':
+ // backslash
+ buff.append("\\\\");
+ break;
+ default:
+ int ch = (c & 0xffff);
+ if (ch >= ' ' && (ch < 0x80)) {
+ buff.append(c);
+ // not supported in properties files
+ // } else if(ch < 0xff) {
+ // buff.append("\\");
+ // // make sure it's three characters (0x200 is octal
+ // 1000)
+ // buff.append(Integer.toOctalString(0x200 |
+ // ch).substring(1));
+ } else {
+ buff.append("\\u");
+ // make sure it's four characters
+ buff.append(Integer.toHexString(0x10000 | ch).substring(1));
+ }
+ }
+ }
+ return buff.toString();
+ }
+
+ static String quoteString(String result) {
+ if (result == null) {
+ return "null";
+ }
+ return "\"" + javaEncode(result) + "\"";
+ }
+
+ static String quoteArray(Class clazz, String name, Object[] array) {
+ if (array == null) {
+ return "null";
+ }
+ StringBuffer buff = new StringBuffer("new ");
+ buff.append(name);
+ buff.append("[]{");
+ for (int i = 0; i < array.length; i++) {
+ if (i > 0) {
+ buff.append(", ");
+ }
+ buff.append(quote(clazz, array[i]));
+ }
+ buff.append("}");
+ return buff.toString();
+ }
+
+ private static String quoteLongArray(long[] array) {
+ if (array == null) {
+ return "null";
+ }
+ StringBuffer buff = new StringBuffer("new long[]{");
+ for (int i = 0; i < array.length; i++) {
+ if (i > 0) {
+ buff.append(", ");
+ }
+ buff.append(array[i] + "L");
+ }
+ buff.append("}");
+ return buff.toString();
+ }
+
+ private static String quoteStringArray(String[] array) {
+ if (array == null) {
+ return "null";
+ }
+ StringBuffer buff = new StringBuffer("new String[]{");
+ for (int i = 0; i < array.length; i++) {
+ if (i > 0) {
+ buff.append(", ");
+ }
+ buff.append(quoteString(array[i]));
+ }
+ buff.append("}");
+ return buff.toString();
+ }
+
+ static String quoteCredentials(Credentials credentials) {
+ if (credentials == null) {
+ return null;
+ } else if (credentials instanceof SimpleCredentials) {
+ SimpleCredentials sc = (SimpleCredentials) credentials;
+ String user = sc.getUserID();
+ // TODO log attribute names
+ // String[] attributeNames = sc.getAttributeNames();
+ // TODO option to log the password
+ // String pwd = "- hidden -"; // new String(sc.getPassword());
+ return JcrUtils.CLASSNAME + ".createSimpleCredentials("
+ + quoteString(user) + ")";
+ } else {
+ // TODO serialize credentials
+ return "?" + credentials.getClass().getName() + ":"
+ + credentials.toString() + "?";
+ }
+ }
+
+ static String quoteArgs(Class[] argClasses, Object[] args) {
+ if (args == null) {
+ return "";
+ }
+ StringBuffer buff = new StringBuffer();
+ for (int i = 0; i < args.length; i++) {
+ if (i > 0) {
+ buff.append(", ");
+ }
+ buff.append(StringUtils.quote(argClasses[i], args[i]));
+ }
+ return buff.toString();
+ }
+
+ /**
+ * Format an object as Java source code.
+ *
+ * @param o the object
+ * @return the formatted string
+ */
+ public static String quoteSimple(Object o) {
+ if (o instanceof String) {
+ return quoteString((String) o);
+ } else if (o.getClass().isArray()) {
+ if (o instanceof String[]) {
+ return quoteStringArray((String[]) o);
+ } else if (o instanceof long[]) {
+ return quoteLongArray((long[]) o);
+ } else {
+ return null;
+ }
+ } else if (o instanceof Integer) {
+ return o.toString();
+ } else if (o instanceof Long) {
+ return o.toString() + "L";
+ } else if (o instanceof Boolean) {
+ return o.toString();
+ } else if (o instanceof Double) {
+ return o.toString() + "d";
+ } else if (o instanceof Calendar) {
+ return quoteCalendar((Calendar) o);
+ }
+ return null;
+ }
+
+ /**
+ * Format an object as Java source code.
+ *
+ * @param clazz the class
+ * @param o the object
+ * @return the formatted string
+ */
+ public static String quote(Class clazz, Object o) {
+ if (o == null) {
+ if (clazz == void.class) {
+ return "";
+ }
+ if (clazz.isArray()) {
+ return "(" + clazz.getComponentType().getName() + "[])null";
+ } else {
+ return "(" + clazz.getName() + ")null";
+ }
+ } else if (o instanceof Credentials) {
+ return quoteCredentials((Credentials) o);
+ } else if (o instanceof String) {
+ return quoteString((String) o);
+ } else if (o.getClass().isArray()) {
+ if (o instanceof String[]) {
+ return quoteStringArray((String[]) o);
+ } else if (o instanceof long[]) {
+ return quoteLongArray((long[]) o);
+ } else {
+ Class ct = o.getClass().getComponentType();
+ LogObject.InterfaceDef idef = LogObject.getInterface(ct);
+ if (idef == null) {
+ throw new Error("unsupported class: " + o.getClass());
+ }
+ return quoteArray(idef.interfaceClass, idef.className,
+ (Object[]) o);
+ }
+ } else if (o instanceof Integer) {
+ if (clazz == int.class) {
+ return o.toString();
+ } else {
+ // TODO doesn't work yet in player
+ return "new Integer(" + o.toString() + ")";
+ }
+ } else if (o instanceof Long) {
+ if (clazz == long.class) {
+ return o.toString() + "L";
+ } else {
+ // TODO doesn't work yet in player
+ return "new Long(" + o.toString() + ")";
+ }
+ } else if (o instanceof Boolean) {
+ if (clazz == boolean.class) {
+ return o.toString();
+ } else {
+ // TODO doesn't work yet in player
+ return "Boolean.valueOf(" + o.toString() + ")";
+ }
+ } else if (o instanceof EventListener) {
+ return JcrUtils.CLASSNAME
+ + ".createDoNothingEventListener()";
+ } else if (o instanceof ItemVisitor) {
+ return JcrUtils.CLASSNAME
+ + ".createDoNothingItemVisitor()";
+ } else if (o instanceof Proxy) {
+ LogObject obj = (LogObject) Proxy.getInvocationHandler(o);
+ return obj.getObjectName();
+ } else if (o instanceof LogObject) {
+ return ((LogObject) o).getObjectName();
+ } else if (o instanceof Double) {
+ return o.toString() + "d";
+ } else if (o instanceof Calendar) {
+ return quoteCalendar((Calendar) o);
+ } else if (o instanceof OutputStream) {
+ return quoteOutputStream((OutputStream) o);
+ } else if (o instanceof InputStream) {
+ return quoteInputStream((InputStream) o);
+ } else if (o instanceof org.xml.sax.ContentHandler) {
+ return JcrUtils.CLASSNAME
+ + ".createDoNothingEventListener()";
+ } else {
+ StringBuffer buff = new StringBuffer();
+ try {
+ String s = serializeToString(o);
+ buff.append("/* UNKNOWN OBJECT: ");
+ buff.append(o.toString());
+ buff.append(" */ (");
+ buff.append(o.getClass().getName());
+ buff.append(")");
+ buff.append(JcrUtils.CLASSNAME);
+ buff.append(".deserializeFromString(\"");
+ buff.append(s);
+ buff.append("\")");
+ } catch (Exception e) {
+ buff.append("/* UNKNOWN UNSERIALIZABLE OBJECT: ");
+ buff.append(o.toString());
+ buff.append(" (");
+ buff.append(o.getClass().getName());
+ buff.append(") */ null");
+ }
+ return buff.toString();
+ }
+ }
+
+ private static String quoteOutputStream(OutputStream stream) {
+ StringBuffer buff = new StringBuffer(JcrUtils.CLASSNAME);
+ buff.append(".getOutputStream()");
+ return buff.toString();
+ }
+
+ private static String quoteInputStream(InputStream stream) {
+ StringBuffer buff = new StringBuffer(JcrUtils.CLASSNAME);
+ buff.append(".getInputStream(\"");
+ buff.append(stream.toString());
+ buff.append("\")");
+ return buff.toString();
+ }
+
+ private static String quoteCalendar(Calendar cal) {
+ StringBuffer buff = new StringBuffer(JcrUtils.CLASSNAME);
+ buff.append(".getCalendar(\"");
+ buff.append(DATE_FORMAT.format(cal.getTime()));
+ buff.append("\")");
+ return buff.toString();
+ }
+
+ static Calendar parseCalendar(String s) {
+ Date d;
+ try {
+ d = DATE_FORMAT.parse(s);
+ } catch (ParseException e) {
+ throw new Error("Can not parse date: " + s);
+ }
+ // TODO calendar: timezones are not set here
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(d);
+ return cal;
+ }
+
+ static String convertBytesToString(byte[] value) {
+ StringBuffer buff = new StringBuffer(value.length * 2);
+ for (int i = 0; value != null && i < value.length; i++) {
+ int c = value[i] & 0xff;
+ buff.append(Integer.toHexString((c >> 4) & 0xf));
+ buff.append(Integer.toHexString(c & 0xf));
+ }
+ return buff.toString();
+ }
+
+ static byte[] convertStringToBytes(String s) throws IllegalArgumentException, NumberFormatException {
+ int len = s.length();
+ if (len % 2 == 1) {
+ throw new IllegalArgumentException("Hex String with odd number of characters: " + s);
+ }
+ len /= 2;
+ byte[] buff = new byte[len];
+ for (int i = 0; i < len; i++) {
+ String t = s.substring(i + i, i + i + 2);
+ buff[i] = (byte) Integer.parseInt(t, 16);
+ }
+ return buff;
+ }
+
+ static String serializeToString(Object obj) throws IOException {
+ byte[] bytes = serialize(obj);
+ return convertBytesToString(bytes);
+ }
+
+ private static byte[] serialize(Object obj) throws IOException {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ObjectOutputStream os = new ObjectOutputStream(out);
+ os.writeObject(obj);
+ return out.toByteArray();
+ }
+
+ /**
+ * Check if this string looks like a UUID.
+ *
+ * @param id
+ * @return if the id is formatted correctly
+ */
+ public static boolean isUUID(String id) {
+ // example: "deab5a60-01d3-472f-bc86-4d2bdeb06470"
+ if (id == null || id.length() != 36) {
+ return false;
+ }
+ for (int i = 0; i < id.length(); i++) {
+ char ch = id.charAt(i);
+ switch(i) {
+ case 8:
+ case 13:
+ case 18:
+ case 23:
+ if (ch != '-') {
+ return false;
+ }
+ break;
+ default:
+ if ((ch < '0' || ch > '9') && (ch < 'a' || ch > 'f') && (ch < 'A' || ch > 'F')) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+}
Propchange: jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/StringUtils.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/package.html
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/package.html?view=auto&rev=540521
==============================================================================
--- jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/package.html (added)
+++ jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/package.html Tue May 22 03:26:30 2007
@@ -0,0 +1,41 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<body>
+<p>
+Contains the Log Wrapper implementation for the JCR API.
+The Log Wrapper is used to log application method calls to a JCR implementation,
+for example Jackrabbit. The generated log contains all method calls to all
+methods of the JCR API, together with the parameter values used.
+The file is human readable and contains Java source code.
+</p>
+There are two ways to use the Log Wrapper:
+<ul>
+<li>
+ Just after opening the 'real' repository (for example a Jackrabbit repository),
+ wrap it using:<br />
+ {@link org.apache.jackrabbit.jcrlog.RepositoryLogger#wrap(javax.jcr.Repository, java.lang.String) RepositoryLogger.wrap(theRepository, settings)}.
+</li>
+<li>
+ Instantiate the repository using:<br />
+ RepositoryFactory.open(url).
+ <br />
+ {@link org.apache.jackrabbit.jcrlog.RepositoryFactory#open(java.lang.String) RepositoryFactory.open(url)}.
+</li>
+</ul>
+Afterwards, the repository can be used in the usual way.
+All other classes are not meant to be used by the application directly.
+</body>
Propchange: jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/package.html
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/Arg.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/Arg.java?view=auto&rev=540521
==============================================================================
--- jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/Arg.java (added)
+++ jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/Arg.java Tue May 22 03:26:30 2007
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.jcrlog.player;
+
+import org.apache.jackrabbit.jcrlog.StringUtils;
+
+/**
+ * A function call argument used by the statement.
+ *
+ * @author Thomas Mueller
+ *
+ */
+class Arg {
+ private Player player;
+ private Class clazz;
+ private Object obj;
+ private Statement stat;
+
+ Arg(Player player, Class clazz, Object obj) {
+ this.player = player;
+ this.clazz = clazz;
+ this.obj = obj;
+ }
+
+ Arg(Statement stat) {
+ this.stat = stat;
+ }
+
+ public String toString() {
+ if (stat != null) {
+ return stat.toString();
+ } else {
+ return StringUtils.quote(clazz, getValue());
+ }
+ }
+
+ void execute() throws Exception {
+ if (stat != null) {
+ stat.execute();
+ clazz = stat.getReturnClass();
+ obj = stat.getReturnObject();
+ stat = null;
+ }
+ }
+
+ Class getValueClass() {
+ return clazz;
+ }
+
+ Object getValue() {
+ if (obj == null) {
+ return null;
+ } else if (clazz == String.class) {
+ return player.getUUID((String)obj);
+ } else if (clazz == String[].class) {
+ String[] now = (String[])obj;
+ String[] result = new String[now.length];
+ for (int i = 0; i < now.length; i++) {
+ result[i] = player.getUUID(now[i]);
+ }
+ return result;
+ } else {
+ return obj;
+ }
+ }
+}
\ No newline at end of file
Propchange: jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/Arg.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/Parser.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/Parser.java?view=auto&rev=540521
==============================================================================
--- jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/Parser.java (added)
+++ jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/Parser.java Tue May 22 03:26:30 2007
@@ -0,0 +1,312 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.jcrlog.player;
+
+import java.util.ArrayList;
+
+import javax.jcr.Value;
+
+import org.apache.jackrabbit.jcrlog.StringUtils;
+
+/**
+ * The parser to parse a statement (a single line in the log file).
+ *
+ * @author Thomas Mueller
+ *
+ */
+class Parser {
+ private final static int STRING = 0, NAME = 1, NUMBER = 2, SPECIAL = 3;
+
+ private Player player;
+
+ private Statement stat;
+
+ private String line;
+
+ private String token;
+
+ private int tokenType;
+
+ private int pos;
+
+ static Statement parseStatement(Player player, String line) {
+ Parser p = new Parser(player, line);
+ p.parseStatement();
+ return p.stat;
+ }
+
+ private Parser(Player player, String line) {
+ this.player = player;
+ this.line = line;
+ read();
+ }
+
+ private Statement parseStatement() {
+ stat = new Statement(player);
+ String name = readToken();
+ Object o = player.getObject(name);
+ if (o != null) {
+ // n0.getPath()
+ read(".");
+ String methodName = readToken();
+ parseCall(name, o, methodName);
+ } else {
+ if (readIf(".")) {
+ // java.lang.System.exit(0);
+ parseStaticCall(name);
+ } else {
+ // Node n0 = ...
+ if (readIf("[")) {
+ read("]");
+ }
+ stat.setAssign(name, readToken());
+ read("=");
+ name = readToken();
+ o = player.getObject(name);
+ if (o != null) {
+ // ... = s0.getRootNode();
+ read(".");
+ parseCall(name, o, readToken());
+ } else if (readIf(".")) {
+ // ... = o.a.RepositoryFactory.open("apache/jackrabbit/transient");
+ parseStaticCall(name);
+ }
+ }
+ }
+ return stat;
+ }
+
+ private void read() {
+ while (line.charAt(pos) == ' ') {
+ pos++;
+ }
+ int start = pos;
+ char ch = line.charAt(pos);
+ switch (ch) {
+ case '\"':
+ tokenType = STRING;
+ pos++;
+ while (pos < line.length()) {
+ ch = line.charAt(pos);
+ if (ch == '\\') {
+ pos += 2;
+ } else if (ch == '\"') {
+ pos++;
+ break;
+ } else {
+ pos++;
+ }
+ }
+ break;
+ case '.':
+ case ',':
+ case '(':
+ case ')':
+ case ';':
+ case '{':
+ case '}':
+ case '[':
+ case ']':
+ case '=':
+ tokenType = SPECIAL;
+ pos++;
+ break;
+ default:
+ if (Character.isLetter(ch) || ch == '_') {
+ tokenType = NAME;
+ pos++;
+ while (true) {
+ ch = line.charAt(pos);
+ if (Character.isLetterOrDigit(ch) || ch == '_') {
+ pos++;
+ } else {
+ break;
+ }
+ }
+ } else if (ch == '-' || Character.isDigit(ch)) {
+ tokenType = NUMBER;
+ pos++;
+ while (true) {
+ ch = line.charAt(pos);
+ if (Character.isDigit(ch)
+ || ".+-eElLxabcdefABCDEF".indexOf(ch) >= 0) {
+ pos++;
+ } else {
+ break;
+ }
+ }
+ }
+ }
+ token = line.substring(start, pos);
+ }
+
+ private boolean readIf(String s) {
+ if (token.equals(s)) {
+ read();
+ return true;
+ }
+ return false;
+ }
+
+ private String readToken() {
+ String s = token;
+ read();
+ return s;
+ }
+
+ private void read(String s) {
+ if (!readIf(s)) {
+ throw new Error("expected: " + s + " read: " + token + " in "
+ + line);
+ }
+ }
+
+ private Arg parseValue() {
+ if (tokenType == STRING) {
+ String s = readToken();
+ s = StringUtils.javaDecode(s.substring(1, s.length() - 1));
+ return new Arg(player, String.class, s);
+ } else if (tokenType == NUMBER) {
+ String number = readToken().toLowerCase();
+ if (number.startsWith("0x")) {
+ if (number.endsWith("l")) {
+ Long v = new Long(Long.parseLong(number.substring(2, number
+ .length() - 1), 16));
+ return new Arg(player, long.class, v);
+ } else {
+ Integer v = new Integer(Integer.parseInt(number.substring(
+ 2, number.length() - 1), 16));
+ return new Arg(player, int.class, v);
+ }
+ } else if (number.indexOf("e") >= 0 || number.indexOf(".") >= 0) {
+ Double v = new Double(Double.parseDouble(number));
+ return new Arg(player, double.class, v);
+ } else if (number.endsWith("l")) {
+ Long v = new Long(Long.parseLong(number.substring(0, number
+ .length() - 1)));
+ return new Arg(player, long.class, v);
+ } else {
+ Integer v = new Integer(Integer.parseInt(number));
+ return new Arg(player, int.class, v);
+ }
+ } else if (tokenType == NAME) {
+ if (readIf("true")) {
+ return new Arg(player, boolean.class, Boolean.TRUE);
+ } else if (readIf("false")) {
+ return new Arg(player, boolean.class, Boolean.FALSE);
+ } else if (readIf("null")) {
+ throw new Error(
+ "Null: class not specified. Example: (java.lang.String)null");
+ } else if (readIf("new")) {
+ if (readIf("String")) {
+ read("[");
+ read("]");
+ read("{");
+ ArrayList values = new ArrayList();
+ do {
+ values.add(parseValue().getValue());
+ } while (readIf(","));
+ read("}");
+ String[] list = new String[values.size()];
+ values.toArray(list);
+ return new Arg(player, String[].class, list);
+ } else if (readIf("Value")) {
+ read("[");
+ read("]");
+ ArrayList values = new ArrayList();
+ read("{");
+ do {
+ values.add(parseValue());
+ } while (readIf(","));
+ read("}");
+ // TODO Value[] execution isn't implemented yet (but
+ // should be trivial)
+ Arg[] list = new Arg[values.size()];
+ values.toArray(list);
+ return new Arg(player, Value[].class, list);
+ } else {
+ // TODO support Version[] versions (Workspace.restore)
+ throw new Error("Unsupported constructor: " + readToken());
+ }
+ }
+ String name = readToken();
+ Object obj = player.getObject(name);
+ if (obj != null) {
+ return new Arg(player, obj.getClass(), obj);
+ }
+ read(".");
+ Statement outer = stat;
+ stat = new Statement(player);
+ parseStaticCall(name);
+ Arg s = new Arg(stat);
+ stat = outer;
+ return s;
+ } else if (readIf("(")) {
+ String className = readToken();
+ className = parseClassName(className);
+ if (readIf("[")) {
+ read("]");
+ }
+ className = "[L" + className + ";";
+ read(")");
+ read("null");
+ Class c = Player.getClass(className);
+ return new Arg(player, c, null);
+ } else {
+ throw new Error("Expected value, got: " + readToken() + " in "
+ + line);
+ }
+ }
+
+ private String parseClassName(String clazz) {
+ while (readIf(".")) {
+ clazz += "." + readToken();
+ }
+ return clazz;
+ }
+
+ private void parseCall(String objectName, Object o, String methodName) {
+ stat.setMethodCall(objectName, o, methodName);
+ ArrayList args = new ArrayList();
+ read("(");
+ while (true) {
+ if (readIf(")")) {
+ break;
+ }
+ Arg p = parseValue();
+ args.add(p);
+ if (readIf(")")) {
+ break;
+ }
+ read(",");
+ }
+ stat.setArgs(args);
+ }
+
+ private void parseStaticCall(String clazz) {
+ String last = readToken();
+ // clazz += "." + readToken();
+ while (readIf(".")) {
+ clazz += last == null ? "" : "." + last;
+ last = readToken();
+ }
+ String methodName = last;
+ stat.setStaticCall(clazz);
+ parseCall(null, null, methodName);
+ }
+
+}
Propchange: jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/Parser.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/Player.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/Player.java?view=auto&rev=540521
==============================================================================
--- jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/Player.java (added)
+++ jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/Player.java Tue May 22 03:26:30 2007
@@ -0,0 +1,207 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.jcrlog.player;
+
+import java.io.*;
+import java.util.HashMap;
+
+import org.apache.jackrabbit.jcrlog.LogObject;
+import org.apache.jackrabbit.jcrlog.StringUtils;
+
+/**
+ * The command line tool to re-run the log file. This is done using reflection.
+ *
+ * @author Thomas Mueller
+ *
+ */
+public class Player {
+
+ private boolean log;
+
+ private final static String[] IMPORTED_PACKAGES = { "", "java.lang.",
+ "java.util.", "javax.jcr.", LogObject.MY_PACKAGE_DOT };
+
+ private HashMap objects = new HashMap();
+ private HashMap uuidMap = new HashMap();
+ private String lastUUID;
+ private String lastReturn;
+ private boolean checkResults;
+
+ /**
+ * Execute a trace file using the command line. The log file name to execute (replayed) must be specified
+ * as the last parameter. The following optional command line parameters are supported:
+ * <ul>
+ * <li><code>-log</code> to enable logging the executed statement to System.out
+ * <li><code>-checkResults</code> if this is set, the values returned at runtime are compared with the values in the log file
+ * </ul>
+ *
+ * @param args the arguments of the application
+ */
+ public static void main(String[] args) throws Exception {
+ new Player().run(args);
+ }
+
+ /**
+ * Execute a trace file.
+ *
+ * @param fileName
+ * @param log print debug information
+ * @param checkResult if the result of each method should be compared against the result in the file
+ */
+ public static void execute(String fileName, boolean log, boolean checkResult) throws IOException {
+ new Player().runFile(fileName, log);
+ }
+
+ private void run(String[] args) throws IOException {
+ String fileName;
+ try {
+ fileName = args[args.length - 1];
+ for (int i = 0; i < args.length - 1; i++) {
+ if ("-log".equals(args[i])) {
+ log = true;
+ } else if ("-checkResults".equals(args[i])) {
+ checkResults = true;
+ } else {
+ throw new Error("Unknown setting: " + args[i]);
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ System.out.println("Usage: java " + getClass().getName()
+ + " [-log] [-checkResult] <fileName>");
+ return;
+ }
+ runFile(fileName, log);
+ }
+
+ void addUUID(String oldId, String newId) {
+ if (StringUtils.isUUID(oldId) && StringUtils.isUUID(newId)) {
+ String previous = (String) uuidMap.put(oldId, newId);
+ if (previous != null && !previous.equals(newId)) {
+ log("Duplicate UUID mapping, old:" + oldId + " last:" + previous + " now:" + newId);
+ }
+ }
+ }
+
+ String getUUID(String oldId) {
+ if (StringUtils.isUUID(oldId)) {
+ return (String) uuidMap.get(oldId);
+ }
+ return oldId;
+ }
+
+ private void runFile(String fileName, boolean log) throws IOException {
+ this.log = log;
+ LineNumberReader reader = new LineNumberReader(new BufferedReader(
+ new FileReader(fileName)));
+ while (true) {
+ String line = reader.readLine();
+ if (line == null) {
+ break;
+ }
+ runLine(line.trim());
+ }
+ }
+
+ void log(String s) {
+ if (log) {
+ System.out.println(s);
+ }
+ }
+
+ void logError(String s) {
+ System.out.println("ERROR: " + s);
+ }
+
+ private void runLine(String line) {
+ if (line.startsWith("//return")) {
+ if (line.endsWith("// UUID")) {
+ if (lastUUID == null) {
+ log("WARNING: no UUID returned");
+ } else {
+ int start = line.indexOf('\"');
+ int end = line.lastIndexOf('\"');
+ if (start < 0 || end <= start) {
+ log("WARNING: expected return \"...\"");
+ } else {
+ String uuid = line.substring(start + 1, end);
+ addUUID(uuid, lastUUID);
+ log("> UUID " + uuid + " -> " + lastUUID);
+ }
+ }
+ } else if (checkResults && lastReturn != null) {
+ int start = line.indexOf(' ');
+ int end = line.lastIndexOf(';');
+ if (start >= 0 && end > start) {
+ String expected = line.substring(start, end).trim();
+ if (lastReturn.equals(expected)) {
+ logError("expected: " + expected + " got: " + lastReturn);
+ }
+ }
+ }
+ }
+ if (!line.startsWith("/**/")) {
+ return;
+ }
+ line = line.substring("/**/".length()) + ";";
+ Statement s = Parser.parseStatement(this, line);
+ log("> " + s.toString());
+ try {
+ s.execute();
+ Object result = s.getReturnObject();
+ lastReturn = null;
+ if (result == null) {
+ lastReturn = "null";
+ } else if (result instanceof String) {
+ String r = (String) result;
+ if (StringUtils.isUUID(r)) {
+ lastUUID = r;
+ lastReturn = null;
+ } else {
+ lastUUID = null;
+ lastReturn = r;
+ }
+ } else {
+ lastReturn = StringUtils.quoteSimple(result);
+ }
+ if (lastReturn != null) {
+ log("> return " + lastReturn + ";");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ log("error: " + e.toString());
+ }
+ }
+
+ static Class getClass(String className) {
+ for (int i = 0; i < IMPORTED_PACKAGES.length; i++) {
+ try {
+ return Class.forName(IMPORTED_PACKAGES[i] + className);
+ } catch (ClassNotFoundException e) {
+ }
+ }
+ throw new Error("Class not found: " + className);
+ }
+
+ void assign(String objectName, Object obj) {
+ objects.put(objectName, obj);
+ }
+
+ Object getObject(String name) {
+ return objects.get(name);
+ }
+}
Propchange: jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/Player.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/Statement.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/Statement.java?view=auto&rev=540521
==============================================================================
--- jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/Statement.java (added)
+++ jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/Statement.java Tue May 22 03:26:30 2007
@@ -0,0 +1,206 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.jcrlog.player;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+
+/**
+ * Represents a statement (a single line in the log file).
+ *
+ * @author Thomas Mueller
+ *
+ */
+class Statement {
+ private Player player;
+
+ private boolean assignment;
+
+ private String assignClass;
+
+ private String assignVariable;
+
+ private boolean staticCall;
+
+ private String staticCallClass;
+
+ private String objectName;
+
+ private Object object;
+
+ private String methodName;
+
+ private Arg[] args;
+
+ private Class[] parameterTypes;
+
+ private Object[] parameters;
+
+ private Method method;
+
+ private Class returnClass;
+
+ private Object returnObject;
+
+ Statement(Player player) {
+ this.player = player;
+ }
+
+ private Method findMethod(Class clazz) throws Exception {
+ if ((clazz.getModifiers() & Modifier.PUBLIC) == 0) {
+ // http://forum.java.sun.com/thread.jspa?threadID=704100&messageID=4084720
+ // bug 4071957
+ Class[] interfaces = clazz.getInterfaces();
+ for (int i = 0; i < interfaces.length; i++) {
+ Class c = interfaces[i];
+ if (c.getName().startsWith("javax.")) {
+ try {
+ return c.getMethod(methodName, parameterTypes);
+ } catch (Exception e) {
+ // TODO this is slow, but a workaround for a JVM bug
+ }
+ }
+ }
+ }
+ try {
+ return clazz.getMethod(methodName, parameterTypes);
+ } catch (NoSuchMethodException e) {
+ Method[] methods = clazz.getMethods();
+ methods:
+ for (int i = 0; i < methods.length; i++) {
+ Method m = methods[i];
+ if (methodName.equals(m.getName())) {
+ Class[] argClasses = m.getParameterTypes();
+ for (int j = 0; j < args.length; j++) {
+ if (!argClasses[j].isAssignableFrom(args[j].getValueClass())) {
+ continue methods;
+ }
+ }
+ return m;
+ }
+ }
+ }
+ throw new Error("Method with args not found: " + clazz.getName() + "."
+ + methodName + " args: " + args.length);
+ }
+
+ void execute() throws Exception {
+ if (object == player) {
+ // there was an exception previously
+ player.log("> " + assignVariable + " not set");
+ if (assignment) {
+ player.assign(assignVariable, player);
+ }
+ return;
+ }
+ Class clazz;
+ if (staticCall) {
+ if (staticCallClass == null || staticCallClass.length() == 0
+ || !staticCallClass.startsWith("org.")) {
+ player.log("?class? " + staticCallClass);
+ }
+ clazz = Player.getClass(staticCallClass);
+ } else {
+ clazz = object.getClass();
+ }
+ parameterTypes = new Class[args.length];
+ parameters = new Object[args.length];
+ for (int i = 0; i < args.length; i++) {
+ Arg arg = args[i];
+ arg.execute();
+ parameterTypes[i] = arg.getValueClass();
+ parameters[i] = arg.getValue();
+ }
+ method = findMethod(clazz);
+ returnClass = method.getReturnType();
+ try {
+ Object obj = method.invoke(object, parameters);
+ if (assignment) {
+ player.assign(assignVariable, obj);
+ }
+ returnObject = obj;
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ } catch (InvocationTargetException e) {
+ Throwable t = e.getTargetException();
+ player.log("> " + t.toString());
+ if (assignment) {
+ player.assign(assignVariable, player);
+ }
+ }
+ }
+
+ public String toString() {
+ StringBuffer buff = new StringBuffer();
+ if (assignment) {
+ buff.append(assignClass);
+ buff.append(' ');
+ buff.append(assignVariable);
+ buff.append('=');
+ }
+ if (staticCall) {
+ buff.append(staticCallClass);
+ } else {
+ buff.append(objectName);
+ }
+ buff.append('.');
+ buff.append(methodName);
+ buff.append('(');
+ for (int i = 0; args != null && i < args.length; i++) {
+ if (i > 0) {
+ buff.append(", ");
+ }
+ buff.append(args[i].toString());
+ }
+ buff.append(");");
+ return buff.toString();
+ }
+
+ Class getReturnClass() {
+ return returnClass;
+ }
+
+ Object getReturnObject() {
+ return returnObject;
+ }
+
+ void setAssign(String className, String variableName) {
+ this.assignment = true;
+ this.assignClass = className;
+ this.assignVariable = variableName;
+ }
+
+ void setStaticCall(String className) {
+ this.staticCall = true;
+ this.staticCallClass = className;
+ }
+
+ void setMethodCall(String objectName, Object object, String methodName) {
+ this.objectName = objectName;
+ this.object = object;
+ this.methodName = methodName;
+ }
+
+ public void setArgs(ArrayList list) {
+ args = new Arg[list.size()];
+ list.toArray(args);
+ }
+}
Propchange: jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/Statement.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/package.html
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/package.html?view=auto&rev=540521
==============================================================================
--- jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/package.html (added)
+++ jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/package.html Tue May 22 03:26:30 2007
@@ -0,0 +1,37 @@
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<body>
+<p>
+This package contains the Log Player to replay recorded log files.
+This is useful for example to reproduce a problem, or to measure the speed of an
+operation.
+</p>
+<p>
+The Player can be started from the command line:
+</p>
+<pre>
+java org.apache.jackrabbit.jcrlog.player.Player log.txt
+</pre>
+<p>
+See also: {@link org.apache.jackrabbit.jcrlog.player.Player Player}.
+</p>
+<p>
+All other classes are not meant to be used by the application directly.
+</p>
+</body>
+
Propchange: jackrabbit/trunk/contrib/jcrlog/src/main/java/org/apache/jackrabbit/jcrlog/player/package.html
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/doodle/MyDoodle.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/doodle/MyDoodle.java?view=auto&rev=540521
==============================================================================
--- jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/doodle/MyDoodle.java (added)
+++ jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/doodle/MyDoodle.java Tue May 22 03:26:30 2007
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.jcrlog.doodle;
+
+import javax.jcr.Repository;
+import javax.jcr.Session;
+
+/**
+ * Scratch pad for transient tests.
+ *
+ * @author Thomas Mueller
+ *
+ */
+public class MyDoodle {
+
+ public static void main(String[] args) throws Exception {
+ new MyDoodle().test();
+ }
+
+ public static void println(String s) {
+ System.out.println(s);
+ }
+
+ public void test() throws Exception {
+
+// 11-10 14:13:28
+// > org.apache.jackrabbit.jcrlog.samples.FirstHop.main(FirstHop.java:40)
+ /**/Repository rp0 = org.apache.jackrabbit.jcrlog.RepositoryFactory.open("apache/jackrabbit/transient");
+// > org.apache.jackrabbit.jcrlog.samples.FirstHop.main(FirstHop.java:41)
+ /**/Session s0 = rp0.login();
+// 11-10 14:13:33
+// time: 4672 ms
+// > org.apache.jackrabbit.jcrlog.samples.FirstHop.main(FirstHop.java:43)
+ /**/s0.getUserID();
+// > org.apache.jackrabbit.jcrlog.samples.FirstHop.main(FirstHop.java:44)
+ /**/rp0.getDescriptor("jcr.repository.name");
+// > org.apache.jackrabbit.jcrlog.samples.FirstHop.main(FirstHop.java:48)
+ /**/s0.logout();
+// time: 562 ms
+
+
+ }
+
+}
Propchange: jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/doodle/MyDoodle.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/doodle/MyItemVisitor.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/doodle/MyItemVisitor.java?view=auto&rev=540521
==============================================================================
--- jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/doodle/MyItemVisitor.java (added)
+++ jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/doodle/MyItemVisitor.java Tue May 22 03:26:30 2007
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.jcrlog.doodle;
+
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+import javax.jcr.util.TraversingItemVisitor;
+
+import org.apache.jackrabbit.jcrlog.test.unit.TestAPI;
+
+/**
+ * Template item visitor.
+ *
+ * @author Thomas Mueller
+ *
+ */
+public class MyItemVisitor extends TraversingItemVisitor {
+
+ protected void entering(Property property, int level)
+ throws RepositoryException {
+ TestAPI.println("entering property " + property.getString() + " level "
+ + level);
+ }
+
+ protected void entering(Node node, int level) throws RepositoryException {
+ TestAPI.println("entering node " + node.getName() + " level " + level);
+ }
+
+ protected void leaving(Property property, int level)
+ throws RepositoryException {
+ TestAPI.println("leaving property " + property.getString() + " level "
+ + level);
+ }
+
+ protected void leaving(Node node, int level) throws RepositoryException {
+ TestAPI.println("leaving node " + node.getName() + " level " + level);
+ }
+
+}
Propchange: jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/doodle/MyItemVisitor.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/samples/FirstHop.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/samples/FirstHop.java?view=auto&rev=540521
==============================================================================
--- jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/samples/FirstHop.java (added)
+++ jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/samples/FirstHop.java Tue May 22 03:26:30 2007
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.jcrlog.samples;
+
+import org.apache.jackrabbit.jcrlog.RepositoryFactory;
+
+import javax.jcr.Repository;
+import javax.jcr.Session;
+
+/**
+ * Test application from the Jackrabbit homepage.
+ *
+ */
+public class FirstHop {
+
+ /**
+ * The main entry point of the example application.
+ *
+ * @param args command line arguments (ignored)
+ * @throws Exception if an error occurs
+ */
+ public static void main(String[] args) throws Exception {
+ // Repository repository = new TransientRepository();
+ // Repository repository = RepositoryFactory.open("apache/jackrabbit/transient");
+ // Repository repository = RepositoryLogger.wrap(new TransientRepository(), "file=test.txt;sysout=true");
+ Repository repository = RepositoryFactory.open("apache/jackrabbit/logger/file=test.txt;sysout=true;caller=true;url=apache/jackrabbit/transient");
+ Session session = repository.login();
+ try {
+ String user = session.getUserID();
+ String name = repository.getDescriptor(Repository.REP_NAME_DESC);
+ System.out.println(
+ "Logged in as " + user + " to a " + name + " repository.");
+ } finally {
+ session.logout();
+ }
+ }
+
+}
\ No newline at end of file
Propchange: jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/samples/FirstHop.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/samples/SecondHop.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/samples/SecondHop.java?view=auto&rev=540521
==============================================================================
--- jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/samples/SecondHop.java (added)
+++ jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/samples/SecondHop.java Tue May 22 03:26:30 2007
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.jcrlog.samples;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+
+import org.apache.jackrabbit.jcrlog.RepositoryFactory;
+
+/**
+ * Second hop example. Stores, retrieves, and removes example content.
+ */
+public class SecondHop {
+
+ /**
+ * The main entry point of the example application.
+ *
+ * @param args
+ * command line arguments (ignored)
+ * @throws Exception
+ * if an error occurs
+ */
+ public static void main(String[] args) throws Exception {
+ // Repository repository = new TransientRepository();
+ // Repository repository = RepositoryLogger.wrap(new
+ // TransientRepository(), "file=test.txt;sysout=true");
+ Repository repository = RepositoryFactory
+ .open("apache/jackrabbit/logger/file=test.txt;sysout=true;url=apache/jackrabbit/transient");
+ Session session = repository.login(new SimpleCredentials("username",
+ "password".toCharArray()));
+ try {
+ Node root = session.getRootNode();
+
+ // Store content
+ Node hello = root.addNode("hello");
+ Node world = hello.addNode("world");
+ world.setProperty("message", "Hello, World!");
+ session.save();
+
+ // Retrieve content
+ Node node = root.getNode("hello/world");
+ System.out.println(node.getPath());
+ System.out.println(node.getProperty("message").getString());
+
+ // Remove content
+ root.getNode("hello").remove();
+ session.save();
+ } finally {
+ session.logout();
+ }
+ }
+
+}
Propchange: jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/samples/SecondHop.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/samples/ThirdHop.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/samples/ThirdHop.java?view=auto&rev=540521
==============================================================================
--- jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/samples/ThirdHop.java (added)
+++ jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/samples/ThirdHop.java Tue May 22 03:26:30 2007
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.jcrlog.samples;
+
+import java.io.FileInputStream;
+
+import javax.jcr.ImportUUIDBehavior;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.Property;
+import javax.jcr.PropertyIterator;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.jcr.Value;
+
+import org.apache.jackrabbit.jcrlog.RepositoryFactory;
+
+/**
+ * Third Jackrabbit example application. Imports an example XML file
+ * and outputs the contents of the entire workspace.
+ */
+public class ThirdHop {
+
+ /** Runs the ThirdHop example. */
+ public static void main(String[] args) throws Exception {
+ // Set up a Jackrabbit repository with the specified
+ // configuration file and repository directory
+ // Repository repository = new TransientRepository();
+ // Repository repository = RepositoryLogger.wrap(new TransientRepository(), "file=test.txt;stream=true;sysout=true");
+ Repository repository = RepositoryFactory.open("apache/jackrabbit/logger/file=test.txt;sysout=true;stream=true;url=apache/jackrabbit/transient");
+
+ // Login to the default workspace as a dummy user
+ Session session = repository.login(
+ new SimpleCredentials("username", "password".toCharArray()));
+ try {
+ // Use the root node as a starting point
+ Node root = session.getRootNode();
+
+ // Import the XML file unless already imported
+ if (!root.hasNode("importxml")) {
+ System.out.print("Importing xml... ");
+ // Create an unstructured node under which to import the XML
+ root.addNode("importxml", "nt:unstructured");
+ // Import the file "test.xml" under the created node
+ FileInputStream xml = new FileInputStream("test.xml");
+ session.importXML(
+ "/importxml", xml, ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
+ xml.close();
+ // Save the changes to the repository
+ session.save();
+ System.out.println("done.");
+ }
+
+ dump(root);
+ } finally {
+ session.logout();
+ }
+ }
+
+ /** Recursively outputs the contents of the given node. */
+ private static void dump(Node node) throws RepositoryException {
+ // First output the node path
+ System.out.println(node.getPath());
+ // Skip the virtual (and large!) jcr:system subtree
+ if (node.getName().equals("jcr:system")) {
+ return;
+ }
+
+ // Then output the properties
+ PropertyIterator properties = node.getProperties();
+ while (properties.hasNext()) {
+ Property property = properties.nextProperty();
+ if (property.getDefinition().isMultiple()) {
+ // A multi-valued property, print all values
+ Value[] values = property.getValues();
+ for (int i = 0; i < values.length; i++) {
+ System.out.println(
+ property.getPath() + " = " + values[i].getString());
+ }
+ } else {
+ // A single-valued property
+ System.out.println(
+ property.getPath() + " = " + property.getString());
+ }
+ }
+
+ // Finally output all the child nodes recursively
+ NodeIterator nodes = node.getNodes();
+ while (nodes.hasNext()) {
+ dump(nodes.nextNode());
+ }
+ }
+
+}
\ No newline at end of file
Propchange: jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/samples/ThirdHop.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/samples/test.xml
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/samples/test.xml?view=auto&rev=540521
==============================================================================
--- jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/samples/test.xml (added)
+++ jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/samples/test.xml Tue May 22 03:26:30 2007
@@ -0,0 +1,50 @@
+<xhtml:html xmlns:xhtml="http://www.w3.org/1999/xhtml"
+ xmlns:mathml="http://www.w3.org/1998/Math/MathML">
+ <xhtml:head><xhtml:title>Three Namespaces</xhtml:title></xhtml:head>
+ <xhtml:body>
+ <xhtml:h1 align="center">An Ellipse and a Rectangle</xhtml:h1>
+ <svg:svg xmlns:svg="http://www.w3.org/2000/svg"
+ width="12cm" height="10cm">
+ <svg:ellipse rx="110" ry="130" />
+ <svg:rect x="4cm" y="1cm" width="3cm" height="6cm" />
+ </svg:svg>
+ <xhtml:p>The equation for ellipses</xhtml:p>
+<mathml:math>
+ <mathml:apply>
+ <mathml:eq/>
+ <mathml:cn> 1 </mathml:cn>
+ <mathml:apply>
+ <mathml:plus/>
+ <mathml:apply>
+ <mathml:divide/>
+ <mathml:apply>
+ <mathml:power/>
+ <mathml:ci> x </mathml:ci>
+ <mathml:cn> 2 </mathml:cn>
+ </mathml:apply>
+ <mathml:apply>
+ <mathml:power/>
+ <mathml:ci> a </mathml:ci>
+ <mathml:cn> 2 </mathml:cn>
+ </mathml:apply>
+ </mathml:apply>
+ <mathml:apply>
+ <mathml:divide/>
+ <mathml:apply>
+ <mathml:power/>
+ <mathml:ci> y </mathml:ci>
+ <mathml:cn> 2 </mathml:cn>
+ </mathml:apply>
+ <mathml:apply>
+ <mathml:power/>
+ <mathml:ci> b </mathml:ci>
+ <mathml:cn> 2 </mathml:cn>
+ </mathml:apply>
+ </mathml:apply>
+ </mathml:apply>
+ </mathml:apply>
+</mathml:math>
+ <xhtml:hr/>
+ <xhtml:p>Last Modified January 10, 2002</xhtml:p>
+ </xhtml:body>
+</xhtml:html>
\ No newline at end of file
Propchange: jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/samples/test.xml
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/test/unit/TestAPI.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/test/unit/TestAPI.java?view=auto&rev=540521
==============================================================================
--- jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/test/unit/TestAPI.java (added)
+++ jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/test/unit/TestAPI.java Tue May 22 03:26:30 2007
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.jcrlog.test.unit;
+
+import org.apache.jackrabbit.jcrlog.RepositoryFactory;
+import org.apache.jackrabbit.jcrlog.player.Player;
+
+import java.io.IOException;
+
+import javax.jcr.Node;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+
+import junit.framework.TestCase;
+
+/**
+ * Simple unit test, checks the basic functionality only.
+ *
+ * @author Thomas Mueller
+ *
+ */
+public class TestAPI extends TestCase {
+
+ public static void main(String[] args) throws Exception {
+ new TestAPI().test();
+ }
+
+ public static void println(String s) {
+ System.out.println(s);
+ }
+
+ public void test() throws Exception {
+ stepCleanRepository();
+ stepRunApp();
+ stepCheckResults();
+ stepCleanRepository();
+ stepReplayLog();
+ stepCheckResults();
+ }
+
+ private Session login(Repository repository) throws RepositoryException {
+ return repository.login(new SimpleCredentials("test", "test"
+ .toCharArray()));
+ }
+
+ private void stepCheckResults() throws RepositoryException {
+ Repository repository = RepositoryFactory
+ .open("apache/jackrabbit/transient");
+ Session session = login(repository);
+ Node root = session.getRootNode();
+ Node test = root.getNode("test");
+ assertNotNull(test);
+ assertEquals("Hello", test.getProperty("name").getString());
+ session.logout();
+ }
+
+ private void stepCleanRepository() throws RepositoryException {
+ Repository repository = RepositoryFactory
+ .open("apache/jackrabbit/transient");
+ Session session = login(repository);
+ Node root = session.getRootNode();
+ if (root.hasNode("test")) {
+ root.getNode("test").remove();
+ session.save();
+ }
+ session.logout();
+ }
+
+ private void stepReplayLog() throws IOException {
+ Player.execute("test.txt", false, true);
+ }
+
+ public void stepRunApp() throws Exception {
+ Repository repository = RepositoryFactory
+ .open("apache/jackrabbit/logger/file=test.txt;url=apache/jackrabbit/transient");
+ // Repository repository =
+ // RepositoryFactory.open("apache/jackrabbit/logger/file=test.txt;sysout=true;url=apache/jackrabbit/transient");
+ Session session = login(repository);
+ Node root = session.getRootNode();
+ Node testNode = root.addNode("test");
+ testNode.setProperty("name", "Hello");
+ session.save();
+ session.logout();
+ }
+}
Propchange: jackrabbit/trunk/contrib/jcrlog/src/test/java/org/apache/jackrabbit/jcrlog/test/unit/TestAPI.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: jackrabbit/trunk/contrib/jcrlog/src/test/resources/log4j.properties
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/contrib/jcrlog/src/test/resources/log4j.properties?view=auto&rev=540521
==============================================================================
--- jackrabbit/trunk/contrib/jcrlog/src/test/resources/log4j.properties (added)
+++ jackrabbit/trunk/contrib/jcrlog/src/test/resources/log4j.properties Tue May 22 03:26:30 2007
@@ -0,0 +1,3 @@
+log4j.logger.org.apache.jackrabbit=WARN,stdout
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
\ No newline at end of file
Propchange: jackrabbit/trunk/contrib/jcrlog/src/test/resources/log4j.properties
------------------------------------------------------------------------------
svn:eol-style = native