/*
* 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.data;
import org.apache.jackrabbit.api.management.DataStoreGarbageCollector;
import org.apache.jackrabbit.api.management.MarkEventListener;
import org.apache.jackrabbit.core.SessionImpl;
import org.apache.jackrabbit.core.gc.GarbageCollector;
import org.apache.jackrabbit.test.AbstractJCRTest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.util.Random;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.ValueFactory;
/**
* Test the DataStore garbage collector.
* This tests that the EventListener is called while scanning the repository.
*
* @author Thomas Mueller
*/
public class GCEventListenerTest extends AbstractJCRTest implements MarkEventListener {
/** logger instance */
private static final Logger LOG = LoggerFactory.getLogger(GCEventListenerTest.class);
private static final String TEST_NODE_NAME = "testGCEventListener";
private boolean gotNullNode;
private boolean gotNode;
private int count;
public void testEventListener() throws Exception {
doTestEventListener(true);
doTestEventListener(false);
}
private void doTestEventListener(boolean allowPmScan) throws Exception {
Node root = testRootNode;
Session session = root.getSession();
if (root.hasNode(TEST_NODE_NAME)) {
root.getNode(TEST_NODE_NAME).remove();
session.save();
}
Node test = root.addNode(TEST_NODE_NAME);
Random random = new Random();
byte[] data = new byte[10000];
for (int i = 0; i < 10; i++) {
Node n = test.addNode("x" + i);
random.nextBytes(data);
ValueFactory vf = session.getValueFactory();
n.setProperty("data", vf.createBinary(new ByteArrayInputStream(data)));
session.save();
if (i % 2 == 0) {
n.remove();
session.save();
}
}
session.save();
SessionImpl si = (SessionImpl) session;
DataStoreGarbageCollector gc = si.createDataStoreGarbageCollector();
DataStore ds = ((GarbageCollector) gc).getDataStore();
if (ds != null) {
ds.clearInUse();
boolean pmScan = gc.isPersistenceManagerScan();
gc.setPersistenceManagerScan(allowPmScan);
gotNullNode = false;
gotNode = false;
gc.setMarkEventListener(this);
gc.mark();
if (pmScan && allowPmScan) {
assertTrue("PM scan without null Node", gotNullNode);
assertFalse("PM scan, but got a real node", gotNode);
} else {
assertFalse("Not a PM scan - but got a null Node", gotNullNode);
assertTrue("Not a PM scan - without a real node", gotNode);
}
int deleted = gc.sweep();
LOG.debug("Deleted " + deleted);
assertTrue("Should delete at least one item", deleted >= 0);
gc.close();
}
}
public String getNodeName(Node n) throws RepositoryException {
if (n == null) {
gotNullNode = true;
return String.valueOf(count++);
} else {
gotNode = true;
return n.getPath();
}
}
public void beforeScanning(Node n) throws RepositoryException {
String s = getNodeName(n);
if (s != null) {
LOG.debug("scanning " + s);
}
}
public void done() {
}
}