arcgissamples\geodatabase\TimeStamperRunner.java
/* Copyright 2010 ESRI * * All rights reserved under the copyright laws of the United States * and applicable international laws, treaties, and conventions. * * You may freely redistribute and use this sample code, with or * without modification, provided you include the original copyright * notice and use restrictions. * * See the use restrictions. * */ package arcgissamples.geodatabase; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.zip.ZipEntry; import com.esri.arcgis.datasourcesGDB.FileGDBWorkspaceFactory; import com.esri.arcgis.geodatabase.Feature; import com.esri.arcgis.geodatabase.FeatureClass; import com.esri.arcgis.geodatabase.Field; import com.esri.arcgis.geodatabase.Fields; import com.esri.arcgis.geodatabase.GeometryDef; import com.esri.arcgis.geodatabase.Workspace; import com.esri.arcgis.geodatabase.esriFeatureType; import com.esri.arcgis.geodatabase.esriFieldType; import com.esri.arcgis.geodatabase.esriSchemaLock; import com.esri.arcgis.geometry.GeographicCoordinateSystem; import com.esri.arcgis.geometry.Point; import com.esri.arcgis.geometry.SpatialReferenceEnvironment; import com.esri.arcgis.geometry.esriGeometryType; import com.esri.arcgis.geometry.esriSRGeoCSType; import com.esri.arcgis.interop.extn.ArcGISExtension; import com.esri.arcgis.interop.extn.Bootstrapper; import com.esri.arcgis.system.AoInitialize; import com.esri.arcgis.system.EngineInitializer; import com.esri.arcgis.system.PropertySet; import com.esri.arcgis.system.UID; import com.esri.arcgis.system.esriLicenseProductCode; import com.esri.arcgis.system.esriLicenseStatus; public class TimeStamperRunner { private static String outputPath = null; private Class ceClass = null; public static void main(String[] args) { try{ //Get the ArcGIS Desktop runtime, if it is available String arcObjectsHome = System.getenv("AGSENGINEJAVA"); //If the ArcGIS Desktop runtime is not available, then report appropriate error to developer if(arcObjectsHome == null){ System.err.println("The TimeStamper sample is designed to work with ArcGIS Engine installed."); System.err.println("You must install ArcGIS Engine and deploy the TimeStamperExt.jar as instructed " + "in this sample's ReadMe.htm file."); System.err.println("Exiting execution of this sample..."); System.exit(0); } String extensionJar = arcObjectsHome + "java" + File.separator + "lib" + File.separator + "ext" + File.separator + "TimeStamperExt.jar"; TimeStamperRunner driver = new TimeStamperRunner(); //get output folder outputPath = getOutputDir(); if(driver.isJarFileValid(extensionJar)){ driver.ceClass = driver.getCEClass(extensionJar).get(0); } EngineInitializer.initializeEngine(); AoInitialize aoInit = new AoInitialize(); driver.initializeArcGISLicenses(aoInit); driver.driveExtension(); aoInit.shutdown(); } catch (Exception e){e.printStackTrace();} } void initializeArcGISLicenses(AoInitialize aoInit) { try { if (aoInit.isProductCodeAvailable(esriLicenseProductCode.esriLicenseProductCodeEngine) == esriLicenseStatus.esriLicenseAvailable) aoInit.initialize(esriLicenseProductCode.esriLicenseProductCodeEngine); } catch (Exception e) {e.printStackTrace();} } /** * Convenience method to generate an output directory based on the operating * system that the sample is being executed on. * * @return A path to the new directory is return */ private static String getOutputDir() { String userDir; //Get the operating systems user profile or home location depending //on which operating system this sample is executed on. if(System.getProperty("os.name").toLowerCase().indexOf("win") > -1){ userDir = System.getenv("UserProfile"); }else{ userDir = System.getenv("HOME"); } String outputDir = userDir + File.separator + "arcgis_sample_output"; System.out.println("Creating output directory - " + outputDir); new File(outputDir).mkdir(); return outputDir; } public void driveExtension() throws Exception { System.out.println("Starting TimeStamperRunner...\n"); System.out.print("Initializing data paths..."); String fgdbName = "timestamper.gdb"; System.out.println("Done."); System.out.print("Creating output folder " + outputPath + " if it does not exist..."); createFolder(outputPath); System.out.println("Done."); System.out.print("Creating local File GDB..."); FileGDBWorkspaceFactory wsFactory = new FileGDBWorkspaceFactory(); wsFactory.create(outputPath, fgdbName, null, 0); System.out.println("Done."); System.out.println("Created a File GDB in the following location: " + outputPath + File.separator + fgdbName); //create a fc in above file gdb and associate class extension with it System.out.print("Creating a feature class in local File GDB..."); Workspace ws = (Workspace) wsFactory.openFromFile(outputPath + File.separator + fgdbName, 0); Fields fields = new Fields(); //iod field Field field = new Field(); field.setName("OBJECTID"); field.setType(esriFieldType.esriFieldTypeOID); fields.addField(field); field = null; //shape field field = new Field(); GeometryDef gdef = new GeometryDef(); gdef.setGeometryType(esriGeometryType.esriGeometryPoint); gdef.setHasM(false); gdef.setHasZ(false); SpatialReferenceEnvironment sre = new SpatialReferenceEnvironment(); GeographicCoordinateSystem gcs = (GeographicCoordinateSystem) sre.createGeographicCoordinateSystem(esriSRGeoCSType.esriSRGeoCS_NAD1983); gcs.setDomain(-400, 400, -400, 400); gdef.setSpatialReferenceByRef(gcs); field.setName("shape"); field.setType(esriFieldType.esriFieldTypeGeometry); field.setGeometryDefByRef(gdef); fields.addField(field); field = null; //source id field field = new Field(); field.setName("SourceID"); field.setType(esriFieldType.esriFieldTypeSmallInteger); fields.addField(field); field = null; //creation Field String creationFieldName = "Created"; field = new Field(); field.setName(creationFieldName); field.setType(esriFieldType.esriFieldTypeDate); fields.addField(field); field = null; //modification Field String modificationFieldName = "ModifiedLast"; field = new Field(); field.setName(modificationFieldName); field.setType(esriFieldType.esriFieldTypeDate); fields.addField(field); field = null; //user Field String userFieldName = "ModifiedBy"; field = new Field(); field.setName(userFieldName); field.setType(esriFieldType.esriFieldTypeString); fields.addField(field); field = null; //create and return feature class String fcName = "timeStamperEvents"; FeatureClass fc = new FeatureClass(ws.createFeatureClass(fcName, fields, null, null, esriFeatureType.esriFTSimple, "shape", "default")); System.out.println("Done."); System.out.print("Adding \"Time Stamper\" extension to " + fcName + "..."); if(fc.getEXTCLSID() == null) { fc.changeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock); // Create a new unique identifier object (UID) and assign the GUID to it. UID extUID = new UID(); extUID.setValue(ceClass); PropertySet propertySet = new PropertySet(); propertySet.setProperty("CREATION_FIELDNAME", creationFieldName); propertySet.setProperty("MODIFICATION_FIELDNAME", modificationFieldName); propertySet.setProperty("USER_FIELDNAME", userFieldName); fc.alterClassExtensionCLSID(extUID, propertySet); fc.changeSchemaLock(esriSchemaLock.esriSharedSchemaLock); } else { System.out.println("Cannot alter EXTCLSID for feature class. One already exists"); } System.out.println("Done."); System.out.print("Adding features to " + fcName + "..."); ws.startEditing(false); ws.startEditOperation(); Feature newFeature = null; try { //add feature 1 newFeature = (Feature) fc.createFeature(); Point point1 = new Point(); point1.setSpatialReferenceByRef(fc.getSpatialReference()); point1.setX(-82.794); point1.setY(40.162); newFeature.setShapeByRef(point1); newFeature.setValue(2, 1); newFeature.store(); newFeature = null; //add feature 2 newFeature = (Feature) fc.createFeature(); Point point2 = new Point(); point2.setSpatialReferenceByRef(fc.getSpatialReference()); point2.setX(-81.394); point2.setY(41.511); newFeature.setShapeByRef(point2); newFeature.setValue(2, 2); newFeature.store(); newFeature = null; //add feature 3 newFeature = (Feature) fc.createFeature(); Point point3 = new Point(); point3.setSpatialReferenceByRef(fc.getSpatialReference()); point3.setX(-84.286); point3.setY(41.598); newFeature.setShapeByRef(point3); newFeature.setValue(2, 3); newFeature.store(); ws.stopEditOperation(); ws.stopEditing(true); } catch(Exception e) { if(ws != null && ws.isBeingEdited()) { ws.stopEditing(false); } e.printStackTrace(); } System.out.println("Done."); System.out.println("\nTimeStamperRunner done.\n Please check the CREATION_FIELDNAME, MODIFICATION_FIELDNAME, " + "and USER_FIELDNAME fields in " + outputPath + "\\" + fgdbName + "\\" + fcName + " for time stamps for new features."); System.out.println("\nTimeStamperRunner Done."); } /* * Returns valid jar file path * @param jarFileName * @return */ private boolean isJarFileValid(String jarFilePath) throws FileNotFoundException { if(jarFilePath.length() == 0 || jarFilePath == null) { System.err.println("Error: Jar file path is empty, null or it contains invalid/unsupported characters."); System.exit(-1); } else { File jarFile = new File(jarFilePath); if(jarFile.exists()) { if(!jarFile.isFile() && !jarFilePath.endsWith(".jar")) { throw new FileNotFoundException("Jar file " + jarFile + " not found. Please verify if name of jar file containing Class Extension is correct."); } } } return true; } /* * Retrieve list of valid SOE classes in specified jar file */ private ArrayList<Class> getCEClass(String jarFilePath) { ArrayList<Class> ceClassList = new ArrayList<Class>(5); //validate input path if(System.getProperty("os.name").toLowerCase().startsWith("windows")) { if(jarFilePath.contains("Program Files")) { jarFilePath = jarFilePath.replace("Program Files", "Progra~1"); } else if(jarFilePath.contains("Program Files (x86)")) { jarFilePath = jarFilePath.replace("Program Files (x86)", "Progra~2"); } } //validate file indicated by jar file name. try { //load classes present inside jar file into memory Bootstrapper.loadExtensionJar(jarFilePath); //retrieve individual contents of jar file JarFile jarFile = new JarFile(jarFilePath); Enumeration<JarEntry> jarContents = jarFile.entries(); while (jarContents.hasMoreElements()) { ZipEntry zipEntry = (ZipEntry) jarContents.nextElement(); if(!zipEntry.isDirectory()) { //ignore current file if it does not end with .class String fileName = zipEntry.getName(); if(fileName.endsWith(".class")) { //retrieve the Class object for current class file String ceFullyQualifiedName = fileName.replace('/', '.').substring(0, fileName.length() - ".class".length()); Class classDef = Class.forName(ceFullyQualifiedName); //consider class only if its not an interface and its annotated with ArcGISExtension if(!classDef.isInterface() && classDef.isAnnotationPresent(ArcGISExtension.class)) { //add the class to a list ceClassList.add(classDef); } } } } //trim the list ceClassList.trimToSize(); //if list is of size 0 if(ceClassList.size() <= 0) { System.err.println("\nError: No .class files or .class files containing Class Extension found in " + jarFilePath); } //return it return ceClassList; } catch (IOException e) { e.printStackTrace(); } catch(ClassNotFoundException ce) { ce.printStackTrace(); } return null; } /** * Creates a new directory * @param pathName String */ public void createFolder(String pathName) { File f = new File(pathName); if (!f.exists()) { f.mkdir(); } } /** * Empties specified directory of all files * @param dirName String */ public void emptyFolder(String dirName, boolean includeSubFolder) throws Exception { File src = new File(dirName); if (src.isDirectory() && src.exists()) { File list[] = src.listFiles(); for (int i = 0; i < list.length; i++) { if (includeSubFolder && list[i].isDirectory()) { emptyFolder(list[i].getPath(), includeSubFolder); list[i].delete(); } else { list[i].delete(); } } } else { throw new Exception("FeatureValidatorDriver.emptyFolder() - " + dirName + " is not a directory or does not exist."); } } /** * Empties specified directory of all files * @param dirName String */ public void deleteFolder(String dirName) throws Exception { File src = new File(dirName); if (src.isDirectory() && src.exists()) { File list[] = src.listFiles(); for (int i = 0; i < list.length; i++) { if (list[i].isDirectory()) { emptyFolder(list[i].getPath(), true); list[i].delete(); } else { list[i].delete(); } } src.delete(); } else { src.delete(); } } /** * Empties specified directory of all files * @param dirName String */ public void deleteFile(String fullyQualifiedFileName) throws Exception { File file = new File(fullyQualifiedFileName); if(!file.isDirectory() && file.exists()) { file.delete(); } else { throw new Exception("MatrixUtil.deleteFile() - File " + fullyQualifiedFileName + " does not exist or is a directory."); } } }