/**
* Copyright 2011 meltmedia
*
* Licensed 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.xchain.framework.lifecycle;
import static org.junit.Assert.*;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import javax.xml.namespace.QName;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.xchain.framework.scanner.ScanException;
/**
* @author Christian Trimble
* @author Devon Tackett
* @author John Trimble
* @author Josh Kennedy
*/
@LifecycleClass(uri="http://www.xchain.org/lifecycle/test-scanner-step-order")
public class LifecycleStepScannerTest
{
public static Logger log = LoggerFactory.getLogger(LifecycleStepScannerTest.class);
protected LifecycleContext context;
@Before public void setUp()
{
context = new LifecycleContext();
context.setClassLoader(new LifecycleClassLoader(Thread.currentThread().getContextClassLoader()));
}
@After public void tearDown()
{
}
@Test public void testLifecycleStepClasses()
throws Exception
{
Iterator<LifecycleStep> stepIterator = getStepIterator();
Stack<QName> stepStack = new Stack<QName>();
stepStack.push(QName.valueOf("{http://www.xchain.org/lifecycle/test-scanner-step-order}step4"));
stepStack.push(QName.valueOf("{http://www.xchain.org/lifecycle/test-scanner-step-order}step3"));
stepStack.push(QName.valueOf("{http://www.xchain.org/lifecycle/test-scanner-step-order}step2"));
stepStack.push(QName.valueOf("{http://www.xchain.org/lifecycle/test-scanner-step-order}step1"));
while( stepIterator.hasNext() && !stepStack.isEmpty() ) {
LifecycleStep step = stepIterator.next();
if( log.isDebugEnabled() ) log.debug("Step: "+step.getQName());
if( step.getQName().equals(stepStack.peek()) )
log.debug("Pop: "+stepStack.pop().toString());
}
assertTrue("Lifecycle step order incorrect.", stepStack.isEmpty());
}
@Test public void testCoreLifecycleStepOrder()
throws Exception
{
String uri = "http://www.xchain.org/framework/lifecycle";
List<LifecycleStep> stepList = getStepList();
isOrderedCorrectly(stepList,
new QName(uri, "default-xml-factory"),
new QName(uri, "xml-factory-lifecycle"),
new QName(uri, "create-config-document-context"),
new QName(uri, "config"),
new QName(uri, "command-engineering")
);
}
@Test public void testImplicitConfigDependency()
throws ScanException
{
String lifecycleUri = "http://www.xchain.org/framework/lifecycle";
String testUri = "http://www.xchain.org/lifecycle/test-scanner-step-order";
List<LifecycleStep> stepList = getStepList();
isOrderedCorrectly(stepList,
new QName(lifecycleUri, "default-xml-factory"),
new QName(testUri, "a-nonconfig-step"), // depends on no one.
new QName(lifecycleUri, "xml-factory-lifecycle"),
new QName(lifecycleUri, "create-config-document-context"),
new QName(lifecycleUri, "config"),
new QName(testUri, "a-config-step"), // implicitly depends upon create-config-document-context.
new QName(lifecycleUri, "command-engineering")
);
}
private String stepListToString(List<LifecycleStep> list) {
StringBuffer buffer = new StringBuffer();
buffer.append("[");
for( LifecycleStep step : list )
buffer.append(step.getQName().getLocalPart()).append(", ");
buffer.append("]");
return buffer.toString();
}
public void isOrderedCorrectly(List<LifecycleStep> stepList, QName... expectedOrder) {
Stack<QName> stepStack = new Stack<QName>();
for( int i = expectedOrder.length - 1; i >= 0; i-- )
stepStack.push(expectedOrder[i]);
for( LifecycleStep step : stepList ) {
if( stepStack.isEmpty() ) break;
if( stepStack.peek().equals(step.getQName()) )
stepStack.pop();
}
assertEquals("Steps were either not executed or executed in the wrong order.", true, stepStack.isEmpty());
}
@StartStep(localName="step2", before={"step3"}, after={"step1"})
public static void startStep2() { }
@StartStep(localName="step4")
public static void startStep4() { }
@StartStep(localName="step1")
public static void startStep1() { }
@StartStep(localName="step3", before={"step4"})
public static void startStep3() { }
@StartStep(localName="a-config-step")
public static void startAConfigStep1(LifecycleContext context, ConfigDocumentContext configContext) { }
@StartStep(localName="a-nonconfig-step")
public static void startANonconfigStep(LifecycleContext context) { }
public List<LifecycleStep> getStepList() throws ScanException {
LifecycleStepScanner scanner = new LifecycleStepScanner(context);
scanner.scan();
return scanner.getLifecycleStepList();
}
public Iterator<LifecycleStep> getStepIterator() throws ScanException {
List<LifecycleStep> stepList = getStepList();
Iterator<LifecycleStep> stepIterator = stepList.iterator();
return stepIterator;
}
}