/*
* 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.core.integration;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Enumeration;
import java.util.Random;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.jcr.Value;
import javax.jcr.ValueFormatException;
import javax.jcr.version.Version;
import javax.jcr.version.VersionHistory;
import junit.framework.TestCase;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.jackrabbit.core.RepositoryImpl;
import org.apache.jackrabbit.core.config.RepositoryConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BackwardsCompatibilityTest extends TestCase {
/**
* Logger instance
*/
private static final Logger log =
LoggerFactory.getLogger(BackwardsCompatibilityTest.class);
public void testBackwardsCompatibility() throws Exception {
File target = new File("target/backwards-compatibility-test");
FileUtils.deleteDirectory(target);
target.mkdirs();
File source = new File("src/test/resources/compatibility.zip");
unpack(source, target);
for (File dir : target.listFiles()) {
if (dir.isDirectory()) {
log.info("Testing backwards compatibility with {}", dir);
assertRepository(dir);
}
}
}
private void assertRepository(File directory) throws Exception {
File configuration = new File(directory, "repository.xml");
try {
RepositoryConfig config = RepositoryConfig.create(
configuration.getPath(), directory.getPath());
RepositoryImpl repository = RepositoryImpl.create(config);
try {
Session session = repository.login(
new SimpleCredentials("admin", "admin".toCharArray()));
try {
assertTestData(session);
} finally {
session.logout();
}
} finally {
repository.shutdown();
}
} catch (RepositoryException e) {
String message = "Unable to access repository " + directory;
log.error(message, e);
fail(message);
}
}
private void assertTestData(Session session) throws Exception {
Node root = session.getRootNode();
assertTrue(root.hasNode("test"));
Node test = root.getNode("test");
Node versionable = assertVersionable(test);
assertProperties(test, versionable);
assertVersionableCopy(test, versionable);
assertLock(test);
assertUsers(session);
}
private Node assertVersionable(Node test) throws RepositoryException {
assertTrue(test.hasNode("versionable"));
Node versionable = test.getNode("versionable");
assertTrue(versionable.isNodeType("nt:myversionable"));
assertTrue(versionable.isNodeType("nt:unstructured"));
assertTrue(versionable.isNodeType("mix:versionable"));
assertFalse(versionable.isCheckedOut());
VersionHistory history = versionable.getVersionHistory();
Version versionB = versionable.getBaseVersion();
String[] labels = history.getVersionLabels(versionB);
assertEquals(1, labels.length);
assertEquals("labelB", labels[0]);
Version versionA = history.getVersionByLabel("labelA");
versionable.restore(versionA, true);
assertEquals("A", versionable.getProperty("foo").getString());
versionable.restore(versionB, true);
assertEquals("B", versionable.getProperty("foo").getString());
return versionable;
}
private void assertProperties(Node test, Node versionable)
throws RepositoryException, PathNotFoundException,
ValueFormatException, IOException {
assertTrue(test.hasNode("properties"));
Node properties = test.getNode("properties");
assertTrue(properties.isNodeType("nt:unstructured"));
assertEquals(true, properties.getProperty("boolean").getBoolean());
assertEquals(0.123456789, properties.getProperty("double").getDouble());
assertEquals(1234567890, properties.getProperty("long").getLong());
Node reference = properties.getProperty("reference").getNode();
assertTrue(reference.isSame(versionable));
assertEquals("test", properties.getProperty("string").getString());
Value[] multiple = properties.getProperty("multiple").getValues();
assertEquals(3, multiple.length);
assertEquals("a", multiple[0].getString());
assertEquals("b", multiple[1].getString());
assertEquals("c", multiple[2].getString());
Calendar calendar = properties.getProperty("date").getDate();
assertEquals(1234567890, calendar.getTimeInMillis());
InputStream stream = properties.getProperty("binary").getStream();
try {
byte[] binary = new byte[100 * 1000];
new Random(1234567890).nextBytes(binary);
assertTrue(Arrays.equals(binary, IOUtils.toByteArray(stream)));
} finally {
stream.close();
}
}
private void assertVersionableCopy(Node test, Node versionable)
throws RepositoryException, IOException {
test.getSession().getWorkspace().copy(
versionable.getPath(),
versionable.getPath() + "-copy");
Node copy = test.getNode(versionable.getName() + "-copy");
copy.remove();
test.save();
}
private void assertLock(Node test) throws RepositoryException {
Node lock = test.getNode("lock");
assertTrue(lock.isLocked());
assertTrue(lock.hasProperty("jcr:lockOwner"));
}
private void assertUsers(Session session) throws RepositoryException {
}
private void unpack(File archive, File dir) throws IOException {
ZipFile zip = new ZipFile(archive);
try {
Enumeration<? extends ZipEntry> entries = zip.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if (entry.getName().startsWith("META-INF")) {
} else if (entry.isDirectory()) {
new File(dir, entry.getName()).mkdirs();
} else {
File file = new File(dir, entry.getName());
file.getParentFile().mkdirs();
InputStream input = zip.getInputStream(entry);
try {
OutputStream output = new FileOutputStream(file);
try {
IOUtils.copy(input, output);
} finally {
output.close();
}
} finally {
input.close();
}
}
}
} finally {
zip.close();
}
}
}