001/**
002 * Copyright 2005-2011 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.kew.plugin;
017
018import org.apache.commons.io.FileUtils;
019import org.junit.Before;
020import org.junit.Test;
021import org.kuali.rice.core.api.CoreConstants;
022import org.kuali.rice.core.api.config.property.Config;
023import org.kuali.rice.core.api.config.property.ConfigContext;
024import org.kuali.rice.core.api.util.ClassLoaderUtils;
025import org.kuali.rice.core.impl.config.property.JAXBConfigImpl;
026import org.kuali.rice.kew.test.KEWTestCase;
027import org.kuali.rice.kew.test.TestUtilities;
028
029import javax.xml.namespace.QName;
030import java.io.File;
031
032import static org.junit.Assert.*;
033
034/**
035 * Tests the ZipFilePluginLoader. The zip file which is checked in has the following format:
036 * 
037 * <pre>
038 *   classes/
039 *   |---&gt; test-classes.txt
040 *   |---&gt; workflow2.xml
041 *   lib/
042 *   |---&gt; test.jar
043 *   META-INF/
044 *   |---&gt; workflow.xml
045 * </pre>
046 * 
047 * <p>
048 * The test.jar which is in the zip file has one resource in it which is named test-lib.txt.
049 * 
050 * <p>
051 * The workflow.xml file has 2 params in it and includes the workflow2.xml file.
052 * 
053 * @author Kuali Rice Team (rice.collab@kuali.org)
054 */
055public class ZipFilePluginLoaderTest extends KEWTestCase {
056
057    private Plugin plugin;
058    private File pluginDir;
059
060    @Before
061    // public void setUp() throws Exception {
062    // super.setUp();
063    // Config config = ConfigContext.getCurrentContextConfig();
064    // if (config == null) {
065    // // because of previously running tests, the config might already be initialized
066    // config = new SimpleConfig();
067    // config.getProperties().put(Config.SERVICE_NAMESPACE, "KEW");
068    // ConfigContext.init(config);
069    // }
070    // // from RiceTestCase if this ever get put into that hierarchy
071    //
072    // }
073    //
074    // @After
075    // public void tearDown() throws Exception {
076    // super.setUp();
077    // try {
078    // plugin.stop();
079    // } catch (Exception e) {
080    // e.printStackTrace();
081    // }
082    // try {
083    // FileUtils.deleteDirectory(pluginDir);
084    // } catch (Exception e) {
085    //
086    // }
087    // }
088    @Test
089    public void testLoad() throws Exception {
090        Config config = ConfigContext.getCurrentContextConfig();
091        if (config == null) {
092            // because of previously running tests, the config might already be initialized
093            config = new JAXBConfigImpl();
094            config.putProperty(CoreConstants.Config.APPLICATION_ID, "KEW");
095            ConfigContext.init(config);
096        }
097
098        File pluginZipFile = new File(this.getBaseDir() + "/src/test/resources/org/kuali/rice/kew/plugin/ziptest.zip");
099        assertTrue(pluginZipFile.exists());
100        assertTrue(pluginZipFile.isFile());
101
102        // create a temp directory to copy the zip file into
103        pluginDir = TestUtilities.createTempDir();
104
105        // copy the zip file
106        FileUtils.copyFileToDirectory(pluginZipFile, pluginDir);
107        pluginZipFile = new File(pluginDir, pluginZipFile.getName());
108        assertTrue(pluginZipFile.exists());
109        pluginZipFile.deleteOnExit();
110
111        // create the ZipFilePluginLoader and load the plugin
112        ZipFilePluginLoader loader = new ZipFilePluginLoader(pluginZipFile, null, ClassLoaderUtils.getDefaultClassLoader(),
113                ConfigContext.getCurrentContextConfig());
114        this.plugin = loader.load();
115        assertNotNull("Plugin should have been successfully loaded.", plugin);
116        // check the plugin name, it's QName should be '{KEW}ziptest', it's plugin name should be 'ziptest'
117        assertEquals("Plugin QName should be '{KEW}ziptest'", new QName("KEW", "ziptest"), plugin.getName());
118
119        // start the plugin
120        this.plugin.start();
121
122        // verify that the plugin was extracted, should be in a directory named the same as the local part of the
123        // QName
124        File extractedDirectory = new File(pluginDir, plugin.getName().getLocalPart());
125        assertTrue("Plugin should have been extracted.", extractedDirectory.exists());
126        assertTrue(extractedDirectory.isDirectory());
127        File[] files = extractedDirectory.listFiles();
128        assertEquals("Should be 3 files", 3, files.length);
129
130        // try loading some classes and checking that things got loaded properly
131        assertNotNull("Resource should exist.", plugin.getClassLoader().getResource("lib-test.txt"));
132        assertNotNull("Resource should exist.", plugin.getClassLoader().getResource("classes-test.txt"));
133
134        // check the config values
135        assertEquals(plugin.getConfig().getProperty("test.param.1"), "test.value.1");
136        assertEquals(plugin.getConfig().getProperty("test.param.2"), "test.value.2");
137        assertEquals(plugin.getConfig().getProperty("test.param.3"), "test.value.3");
138
139        // verify the modification checks on the plugin which drive hot deployment
140        assertFalse("Plugin should not be modifed at this point.", loader.isModified());
141        // record the last modified date of the extracted directory
142        long lastModified = pluginDir.lastModified();
143
144        // sleep for a milliseconds before touching the file, this will help our last modified check so we don't
145        // get the same value
146        Thread.sleep(1000);
147
148        // touch the zip file
149        FileUtils.touch(pluginZipFile);
150        assertTrue("Plugin should be modifed after zip file is touched.", loader.isModified());
151        plugin.stop();
152
153        // reload the plugin
154        this.plugin = loader.load();
155        
156        this.plugin.start();
157        assertFalse("After reload, plugin should no longer be modifed.", loader.isModified());
158
159        // check the last modified date of the extracted directory
160        assertTrue("The extracted directory should have been modified.", pluginDir.lastModified() > lastModified);
161
162        try {
163            plugin.stop();
164        } catch (Exception e) {
165            e.printStackTrace();
166        }
167        try {
168            FileUtils.deleteDirectory(pluginDir);
169        } catch (Exception e) {
170
171        }
172    }
173}