/** * Copyright 2007 ATG DUST Project * * 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 atg.adapter.gsa; import java.beans.PropertyEditor; import java.io.File; import java.net.URL; import java.sql.SQLException; import java.sql.Timestamp; import java.util.Date; import java.util.HashMap; import java.util.Properties; import java.util.Random; import junit.framework.TestCase; import org.apache.log4j.Logger; import atg.beans.DynamicPropertyDescriptor; import atg.core.util.StringUtils; import atg.nucleus.Nucleus; import atg.nucleus.servlet.NucleusServlet; import atg.repository.MutableRepositoryItem; import atg.repository.RepositoryException; import atg.repository.RepositoryPropertyDescriptor; import atg.service.idgen.IdGenerator; import atg.service.idgen.IdGeneratorException; import atg.test.util.DBUtils; /** * A basic GSA test which is expected to be extended than used directly. * Has several utility methods. * @author adwivedi * */ public class GSATest extends TestCase { private final transient Random random = new Random(); private static Logger log = Logger.getLogger(GSATest.class); private HashMap<String, File> mConfigDir = new HashMap<String, File>(); /** * */ public GSATest() { super(); // TODO Auto-generated constructor stub } /* * @see TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); } /* * @see TestCase#tearDown() */ protected void tearDown() throws Exception { super.tearDown(); } /** * Constructor for GSATest. * @param arg0 */ public GSATest(String arg0) { super(arg0); } public File getConfigpath() { return getConfigpath(null); } /** * Returns the configpath for tests * * @return */ public File getConfigpath(String pConfigDirectory) { if (mConfigDir.get(pConfigDirectory) == null) { String configdirname = "config"; String packageName = StringUtils.replace(this.getClass().getPackage().getName(), '.', "/"); if (pConfigDirectory != null) configdirname = pConfigDirectory; String configFolder = packageName + "/data/" + configdirname; URL dataURL = this.getClass().getClassLoader().getResource(configFolder); // Mkdir if (dataURL == null) { URL root = this.getClass().getClassLoader().getResource(packageName); File f = new File(root.getFile()); File f2 = new File(f, "/data/" + configdirname); f2.mkdirs(); dataURL = this.getClass().getClassLoader().getResource(configFolder); } mConfigDir.put(pConfigDirectory ,new File(dataURL.getFile())); } System.setProperty("atg.configpath",((File) mConfigDir.get(pConfigDirectory)).getAbsolutePath()); return (File) mConfigDir.get(pConfigDirectory); } /** * Create a repository in the given configpath using the given repository definitions (Absolute paths) * connecting to the db whose properties are specified in pDBProperties @see DBUtils * Method pMethodName is invoked with the GSARepository passed to it as a parameter. * @param pConfigPathWhereToCreateTheRepository * @param definitionFiles * @param pDBProperties * @param pMethodName * @throws Exception * @throws Exception */ protected void setUpAndTest(File pConfigPathWhereToCreateTheRepository, String[] definitionFiles, Properties pDBProperties, String pMethodName) throws Exception{ String repositoryComponentPath = "/"+getName()+"Repository"; GSATestUtils.getGSATestUtils().initializeMinimalConfigpath(pConfigPathWhereToCreateTheRepository, repositoryComponentPath, definitionFiles, pDBProperties, null, null, null, true); Nucleus n = startNucleus(pConfigPathWhereToCreateTheRepository); GSARepository r = (GSARepository) n.resolveName(repositoryComponentPath); try { getClass().getMethod(pMethodName, new Class[] { GSARepository.class }) .invoke(this, new Object[] { r }); } catch (NoSuchMethodError e) { throw new AssertionError("Please declare a method with name "+pMethodName + " in your class. It must take an atg.adapter.gsa.GSARepository as the only parameter."); } finally{ // if it were null a NPE would have occurred at the earlier dereference //if(n != null) n.stopService(); } } /** * Createa a file using reasonable defaults. * Your definition file should exist in the same package as the test and should be * names <test_name>Repository.xml. Configpath is assumed to be what is returned * * @param pMethodName * @throws Exception * @throws Exception */ protected void setUpAndTest(String pMethodName) throws Exception{ File configPathWhereToCreateTheRepository = getConfigpath(null); String packageName = StringUtils.replace(this.getClass().getPackage() .getName(), '.', "/"); String fileName = packageName+"/"+getName()+"Repository.xml"; URL defaultDefinitionFile = getClass().getResource("/"+fileName); if(defaultDefinitionFile == null )throw new AssertionError("DUDE, I need a file called : "+ fileName +" to start a GSA repository from. "); String[] definitionFiles = new String[]{fileName}; Properties DBProperties = DBUtils.getHSQLDBInMemoryDBConnection(); setUpAndTest(configPathWhereToCreateTheRepository, definitionFiles, DBProperties,pMethodName); } /** * Starts Nucleus using the given config directory * @param configpath * @return */ public static Nucleus startNucleus(File configpath) { return startNucleus(configpath.getAbsolutePath()); } /** * Starts Nucleus given an array of configpath entries * @param configpathStr * @return */ public static Nucleus startNucleus(String configpathStr) { System.setProperty("atg.dynamo.license.read", "true"); System.setProperty("atg.license.read", "true"); NucleusServlet.addNamingFactoriesAndProtocolHandlers(); return Nucleus.startNucleus(new String[] {configpathStr}); } /** * @param dbName * @return * @throws Exception * @throws SQLException */ protected DBUtils initDB(Properties props) throws Exception, SQLException { DBUtils db = new DBUtils(props.getProperty("URL"),props.getProperty("driver"),props.getProperty("user"),props.getProperty("password")); return db; } /** * A Dummy test so smokestack won't report this * class as a failure. * It expects that all *Test.class files have * at least one test. * */ public final void testDummy() { } /** * @param pGSARepository * @param descName * @return * @throws RepositoryException */ protected MutableRepositoryItem createDummyItem(GSARepository pGSARepository, String descName, String pID) throws RepositoryException { GSAItemDescriptor descriptor = (GSAItemDescriptor) pGSARepository .getItemDescriptor(descName); MutableRepositoryItem item = null; boolean compoundPrimaryKey = descriptor.getPrimaryTable().getIdColumnCount() > 1; if(pID == null || pID.trim().length() == 0){ if(compoundPrimaryKey){ item = pGSARepository.createItem(getNewCompoundId(pGSARepository, descriptor), descName); } else item = pGSARepository.createItem(descName); } else{ item= pGSARepository.createItem(pID, descName); } RepositoryPropertyDescriptor[] propDescriptors = (RepositoryPropertyDescriptor[]) descriptor .getPropertyDescriptors(); for (int j = 0; j < propDescriptors.length; j++) { RepositoryPropertyDescriptor propertyDescriptor = propDescriptors[j]; if (propertyDescriptor.isWritable() && !propertyDescriptor.isIdProperty() && propertyDescriptor.isRequired()) { if (propertyDescriptor.isCollectionOrMap()) { } else { Object dummyPropertyValue = generateDummyValue(propertyDescriptor); if (dummyPropertyValue != null) { item.setPropertyValue(propertyDescriptor.getName(), dummyPropertyValue); } } } } return item; } /** * Get a id suitable for creating items of this type. We use out * <code>Repository</code>'s <code>IdGenerator</code>. * * @return a new id, which is unique across all items in this * repository with this item descriptor. * @exception RepositoryException if there is trouble creating the id **/ protected GSAId getNewCompoundId(GSARepository r, GSAItemDescriptor desc) throws RepositoryException { // make sure we have a repository if (r == null) return null; // get the generator to use IdGenerator gen = r.getIdGenerator(); if (gen == null) return null; Class<?>[] types = desc.getIdTypes(); String[] idSpaceNames = desc.getIdSpaceNames(); Object[] newId = new Object[types.length]; if (idSpaceNames.length != types.length) throw new RepositoryException("No ID SPACES ! "+ desc.getItemDescriptorName()); // generate an id in our id space and return it try { for (int i=0;i<types.length;i++) { if (types[i] == String.class) { if(i > 0) newId[i] = "dummyIdPart"; else newId[i] = gen.generateStringId(idSpaceNames[i]); } else { long val = gen.generateLongId(idSpaceNames[i]); if (types[i] == Long.class) newId[i] = Long.valueOf(val); else if (types[i] == Float.class) newId[i] = Float.valueOf((float) val); else if (types[i] == Double.class) newId[i] = Double.valueOf((float) val); else if (types[i] == java.sql.Timestamp.class) newId[i] = new java.sql.Timestamp(val); else if (types[i] == java.util.Date.class) newId[i] = new java.util.Date(val); else newId[i] = Integer.valueOf((int)val); } } } catch (IdGeneratorException ie) { throw new RepositoryException(ie); } return desc.generateGSAId(newId); } @SuppressWarnings("unchecked") protected Object generateDummyValue(RepositoryPropertyDescriptor propertyDescriptor) { if (getEnumeratedValues(propertyDescriptor) != null) { return null;// ignore enums for now. } if (propertyDescriptor.getPropertyType().isAssignableFrom( java.lang.String.class)) { return generateString(); } else if (propertyDescriptor.getPropertyType().isAssignableFrom( java.lang.Integer.class)) { return generateInteger(); } else if (propertyDescriptor.getPropertyType().isAssignableFrom( java.lang.Boolean.class)) { return generateBoolean(); } else if (propertyDescriptor.getPropertyType().isAssignableFrom( java.lang.Byte.class)) { return generateByte(); } else if (propertyDescriptor.getPropertyType().isAssignableFrom( java.lang.Short.class)) { return generateShort(); } else if (propertyDescriptor.getPropertyType().isAssignableFrom( java.lang.Long.class)) { return generateLong(); } else if (propertyDescriptor.getPropertyType().isAssignableFrom( java.lang.Float.class)) { return generateFloat(); } else if (propertyDescriptor.getPropertyType().isAssignableFrom( java.lang.Double.class)) { return generateDouble(); } else if (propertyDescriptor.getPropertyType().isAssignableFrom( (new byte[0]).getClass()))//BINARY { return null; // return generateBinary(); } else if (propertyDescriptor.getPropertyType().isAssignableFrom( java.sql.Timestamp.class)) { return generateTimestamp(); } else if (propertyDescriptor.getPropertyType().isAssignableFrom( java.sql.Date.class)) { return generateDate(); } return null; } /** * * Returns the set of enumerated values, or null if there are none **/ String[] getEnumeratedValues(DynamicPropertyDescriptor pDescriptor) { if(pDescriptor == null) return null; PropertyEditor pe = getPropertyEditor(pDescriptor); String[] ret = (pe == null) ? null : pe.getTags(); // make sure it's not just a boolean value Class<?> type = pDescriptor.getPropertyType(); if ((type == Boolean.class || type == Boolean.TYPE) && ret != null && ret.length == 2 && (("true".equals(ret[0]) && "false".equals(ret[1])) || ("false" .equals(ret[0]) && "true".equals(ret[1])))) { return null; } else { return ret; } } /** * * Returns an instance of the property editor, null if there is no * property editor **/ PropertyEditor getPropertyEditor(DynamicPropertyDescriptor pDescriptor) { if(pDescriptor == null ) return null; Class<?> peclass = pDescriptor.getPropertyEditorClass(); if (peclass == null) { return pDescriptor.getUIPropertyEditor(); } else { Object peinst = null; try { peinst = peclass.newInstance(); } catch (InstantiationException e) { log.error("Error: ", e); } catch (IllegalAccessException e) { log.error("Error: ", e); } if (peinst instanceof PropertyEditor) { return (PropertyEditor) peinst; } else { return null; } } } /** * @return */ private Object generateDate() { return new Date(System.currentTimeMillis()); } /** * @return */ private Object generateTimestamp() { return new Timestamp(System.currentTimeMillis()); } // /** // * @return // */ // private Object generateBinary() { // byte[] bytes = new byte[100]; // Random random = new Random(); // random.nextBytes(bytes); // return bytes; // } /** * @return */ private Object generateDouble() { return new Double(random.nextDouble()); } /** * @return */ private Object generateInteger() { return Integer.valueOf(random.nextInt(32768)); } /** * @return */ private Object generateFloat() { return new Float(random.nextFloat()); } /** * @return */ private Object generateLong() { return Long.valueOf(random.nextInt(32278)); } /** * @return */ private Object generateShort() { return Short.valueOf((short) (random.nextInt(100))); } /** * @return */ private Object generateByte() { byte[] bytes = new byte[1]; random.nextBytes(bytes); return Byte.valueOf(bytes[0]); } /** * @return */ private Object generateBoolean() { return Boolean.valueOf(random.nextBoolean()); } /** * @return */ private Object generateString() { return "DUMMY STRING " + generateInteger(); } }