cleanup
authorchrislovsund@netbeans.org
Wed, 05 Jun 2013 21:45:20 +0200
changeset 434d73f85f843ce
parent 432 dc728e292a17
child 435 b54ad40214b0
cleanup
EADS-3772 - use of system property netbeans.user has been obsoleted in favor of InstalledFileLocator/Places
PLSQL/Utilities/nbproject/project.xml
PLSQL/Utilities/src/org/netbeans/modules/plsql/utilities/localization/PlsqlFileLocatorServiceImpl.java
Utilities/Oracle/src/org/netbeans/modules/plsqlsupport/db/DatabaseContentManager.java
     1.1 --- a/PLSQL/Utilities/nbproject/project.xml	Tue Jun 04 16:42:05 2013 +0200
     1.2 +++ b/PLSQL/Utilities/nbproject/project.xml	Wed Jun 05 21:45:20 2013 +0200
     1.3 @@ -109,6 +109,14 @@
     1.4                      </run-dependency>
     1.5                  </dependency>
     1.6                  <dependency>
     1.7 +                    <code-name-base>org.openide.modules</code-name-base>
     1.8 +                    <build-prerequisite/>
     1.9 +                    <compile-dependency/>
    1.10 +                    <run-dependency>
    1.11 +                        <specification-version>7.32.1</specification-version>
    1.12 +                    </run-dependency>
    1.13 +                </dependency>
    1.14 +                <dependency>
    1.15                      <code-name-base>org.openide.nodes</code-name-base>
    1.16                      <build-prerequisite/>
    1.17                      <compile-dependency/>
     2.1 --- a/PLSQL/Utilities/src/org/netbeans/modules/plsql/utilities/localization/PlsqlFileLocatorServiceImpl.java	Tue Jun 04 16:42:05 2013 +0200
     2.2 +++ b/PLSQL/Utilities/src/org/netbeans/modules/plsql/utilities/localization/PlsqlFileLocatorServiceImpl.java	Wed Jun 05 21:45:20 2013 +0200
     2.3 @@ -41,14 +41,9 @@
     2.4   */
     2.5  package org.netbeans.modules.plsql.utilities.localization;
     2.6  
     2.7 -import java.util.Collection;
     2.8 -import org.netbeans.modules.plsqlsupport.db.DatabaseConnectionManager;
     2.9 -import org.netbeans.modules.plsql.lexer.PlsqlBlockType;
    2.10 -import org.netbeans.modules.plsql.utilities.PlsqlFileLocatorService;
    2.11 -import org.netbeans.modules.plsql.utilities.PlsqlSearchObject;
    2.12 -import org.netbeans.modules.plsql.utilities.validation.PlsqlFileValidatorImpl;
    2.13  import java.io.File;
    2.14  import java.io.IOException;
    2.15 +import java.util.Collection;
    2.16  import java.util.HashMap;
    2.17  import java.util.Map;
    2.18  import java.util.logging.Level;
    2.19 @@ -56,11 +51,17 @@
    2.20  import org.netbeans.api.project.Project;
    2.21  import org.netbeans.api.project.ProjectInformation;
    2.22  import org.netbeans.api.project.ProjectUtils;
    2.23 +import org.netbeans.modules.plsql.lexer.PlsqlBlockType;
    2.24 +import org.netbeans.modules.plsql.utilities.PlsqlFileLocatorService;
    2.25 +import org.netbeans.modules.plsql.utilities.PlsqlSearchObject;
    2.26 +import org.netbeans.modules.plsql.utilities.validation.PlsqlFileValidatorImpl;
    2.27 +import org.netbeans.modules.plsqlsupport.db.DatabaseConnectionManager;
    2.28  import org.openide.filesystems.FileObject;
    2.29  import org.openide.filesystems.FileUtil;
    2.30  import org.openide.loaders.DataFolder;
    2.31  import org.openide.loaders.DataObject;
    2.32  import org.openide.loaders.DataObjectNotFoundException;
    2.33 +import org.openide.modules.Places;
    2.34  import org.openide.util.Exceptions;
    2.35  import org.openide.util.lookup.ServiceProvider;
    2.36  
    2.37 @@ -71,115 +72,115 @@
    2.38  @ServiceProvider(service = PlsqlFileLocatorService.class)
    2.39  public class PlsqlFileLocatorServiceImpl implements PlsqlFileLocatorService {
    2.40  
    2.41 -   private static final String cacheDir = System.getProperty("netbeans.user") + "/var/cache/localplsql";
    2.42 -   private final Map<String, PlsqlProjectFileCacheManager> cachePerProject = new HashMap<String, PlsqlProjectFileCacheManager>(); //NOPMD
    2.43 -   private final static Logger logger = Logger.getLogger(PlsqlFileLocatorServiceImpl.class.getName());
    2.44 +    private static final File cacheDir = Places.getCacheSubdirectory("localplsql");
    2.45 +    private final Map<String, PlsqlProjectFileCacheManager> cachePerProject = new HashMap<String, PlsqlProjectFileCacheManager>(); //NOPMD
    2.46 +    private final static Logger logger = Logger.getLogger(PlsqlFileLocatorServiceImpl.class.getName());
    2.47  
    2.48 -   @Override
    2.49 -   public void registerFolder(final String projectName, final FileObject rootFolder) {
    2.50 -      if (projectName == null || rootFolder == null) {
    2.51 -         throw new IllegalArgumentException("arguments cannot be null");
    2.52 -      }
    2.53 -      logger.log(Level.INFO, "Register for project [{0}] with rootFolder [{1}]", new Object[]{projectName, rootFolder});
    2.54 -      PlsqlProjectFileCacheManager pfl = cachePerProject.get(projectName);
    2.55 -      if (pfl == null) {
    2.56 -         pfl = new PlsqlProjectFileCacheManager(FileUtil.toFile(rootFolder), new File(cacheDir, projectName + ".cache"));
    2.57 -      }
    2.58 -      pfl.init();
    2.59 -      cachePerProject.put(projectName, pfl);
    2.60 -   }
    2.61 +    @Override
    2.62 +    public void registerFolder(final String projectName, final FileObject rootFolder) {
    2.63 +        if (projectName == null || rootFolder == null) {
    2.64 +            throw new IllegalArgumentException("arguments cannot be null");
    2.65 +        }
    2.66 +        logger.log(Level.INFO, "Register for project [{0}] with rootFolder [{1}]", new Object[]{projectName, rootFolder});
    2.67 +        PlsqlProjectFileCacheManager pfl = cachePerProject.get(projectName);
    2.68 +        if (pfl == null) {
    2.69 +            pfl = new PlsqlProjectFileCacheManager(FileUtil.toFile(rootFolder), new File(cacheDir, projectName + ".cache"));
    2.70 +        }
    2.71 +        pfl.init();
    2.72 +        cachePerProject.put(projectName, pfl);
    2.73 +    }
    2.74  
    2.75 -   @Override
    2.76 -   public void rebuildCache(final Project project) {
    2.77 -      if (project == null || !cachePerProject.containsKey(getProjectName(project))) {
    2.78 -         throw new IllegalArgumentException("arguments cannot be null");
    2.79 -      }
    2.80 -      logger.log(Level.INFO, "Rebuild cache for project [{0}] ", new Object[]{getProjectName(project)});
    2.81 -      final PlsqlProjectFileCacheManager pfl = cachePerProject.get(getProjectName(project));
    2.82 -      pfl.rebuild();
    2.83 -   }
    2.84 +    @Override
    2.85 +    public void rebuildCache(final Project project) {
    2.86 +        if (project == null || !cachePerProject.containsKey(getProjectName(project))) {
    2.87 +            throw new IllegalArgumentException("arguments cannot be null");
    2.88 +        }
    2.89 +        logger.log(Level.INFO, "Rebuild cache for project [{0}] ", new Object[]{getProjectName(project)});
    2.90 +        final PlsqlProjectFileCacheManager pfl = cachePerProject.get(getProjectName(project));
    2.91 +        pfl.rebuild();
    2.92 +    }
    2.93  
    2.94 -   @Override
    2.95 -   public void unregisterProject(final String projectName) {
    2.96 -      logger.log(Level.INFO, "Remove project [{0}] ", projectName);
    2.97 -      cachePerProject.remove(projectName);
    2.98 -   }
    2.99 +    @Override
   2.100 +    public void unregisterProject(final String projectName) {
   2.101 +        logger.log(Level.INFO, "Remove project [{0}] ", projectName);
   2.102 +        cachePerProject.remove(projectName);
   2.103 +    }
   2.104  
   2.105 -   @Override
   2.106 -   public DataObject getExistingDataObject(final DataObject sourceDataObject, final String objectName, final PlsqlBlockType objectType, final Project project) {
   2.107 -      DataObject targetDataObject = null;
   2.108 -      if (project != null) {
   2.109 -         final String projectName = getProjectName(project);
   2.110 -         final PlsqlSearchObject plsqlSearchObject = new PlsqlSearchObject(objectType, objectName);
   2.111 -         targetDataObject = getDataObject(findFile(projectName, plsqlSearchObject), sourceDataObject, project);
   2.112 -      }
   2.113 -      if (targetDataObject == null) {
   2.114 -         final PlsqlFileValidatorImpl validator = new PlsqlFileValidatorImpl();
   2.115 -         final String fileName = validator.formatFileName(sourceDataObject, objectName, objectType);
   2.116 +    @Override
   2.117 +    public DataObject getExistingDataObject(final DataObject sourceDataObject, final String objectName, final PlsqlBlockType objectType, final Project project) {
   2.118 +        DataObject targetDataObject = null;
   2.119 +        if (project != null) {
   2.120 +            final String projectName = getProjectName(project);
   2.121 +            final PlsqlSearchObject plsqlSearchObject = new PlsqlSearchObject(objectType, objectName);
   2.122 +            targetDataObject = getDataObject(findFile(projectName, plsqlSearchObject), sourceDataObject, project);
   2.123 +        }
   2.124 +        if (targetDataObject == null) {
   2.125 +            final PlsqlFileValidatorImpl validator = new PlsqlFileValidatorImpl();
   2.126 +            final String fileName = validator.formatFileName(sourceDataObject, objectName, objectType);
   2.127  
   2.128 -         if (fileName != null) {
   2.129 -            targetDataObject = getDataObject(FileUtil.toFileObject(new File(fileName)), sourceDataObject, project);
   2.130 -         }
   2.131 -      }
   2.132 -      return targetDataObject;
   2.133 -   }
   2.134 +            if (fileName != null) {
   2.135 +                targetDataObject = getDataObject(FileUtil.toFileObject(new File(fileName)), sourceDataObject, project);
   2.136 +            }
   2.137 +        }
   2.138 +        return targetDataObject;
   2.139 +    }
   2.140  
   2.141 -   private DataObject getDataObject(final FileObject fileObject, final DataObject sourceDataObject, final Project project) {
   2.142 -      if (fileObject == null) {
   2.143 -         return null;
   2.144 -      }
   2.145 -      try {
   2.146 -         final DataObject result = DataFolder.find(fileObject);
   2.147 -         if (project == null || DatabaseConnectionManager.getInstance(project) == null) {
   2.148 -            DatabaseConnectionManager.copyProvider(sourceDataObject, result);
   2.149 -         }
   2.150 -         return result;
   2.151 -      } catch (DataObjectNotFoundException ex) {
   2.152 -         Exceptions.printStackTrace(ex);
   2.153 -      }
   2.154 -      return null;
   2.155 -   }
   2.156 +    private DataObject getDataObject(final FileObject fileObject, final DataObject sourceDataObject, final Project project) {
   2.157 +        if (fileObject == null) {
   2.158 +            return null;
   2.159 +        }
   2.160 +        try {
   2.161 +            final DataObject result = DataFolder.find(fileObject);
   2.162 +            if (project == null || DatabaseConnectionManager.getInstance(project) == null) {
   2.163 +                DatabaseConnectionManager.copyProvider(sourceDataObject, result);
   2.164 +            }
   2.165 +            return result;
   2.166 +        } catch (DataObjectNotFoundException ex) {
   2.167 +            Exceptions.printStackTrace(ex);
   2.168 +        }
   2.169 +        return null;
   2.170 +    }
   2.171  
   2.172 -   FileObject findFile(final String projectName, final PlsqlSearchObject searchObject) {
   2.173 -      if (projectName == null || searchObject == null) {
   2.174 -         throw new IllegalArgumentException("arguments cannot be null");
   2.175 -      }
   2.176 -      final FileObject result = cachePerProject.get(projectName).get(searchObject);
   2.177 -      logger.log(Level.FINE, "Looking for project [{0}] with searchObject [{1}] found [{2}]", new Object[]{projectName, searchObject, result});
   2.178 -      return result;
   2.179 -   }
   2.180 +    FileObject findFile(final String projectName, final PlsqlSearchObject searchObject) {
   2.181 +        if (projectName == null || searchObject == null) {
   2.182 +            throw new IllegalArgumentException("arguments cannot be null");
   2.183 +        }
   2.184 +        final FileObject result = cachePerProject.get(projectName).get(searchObject);
   2.185 +        logger.log(Level.FINE, "Looking for project [{0}] with searchObject [{1}] found [{2}]", new Object[]{projectName, searchObject, result});
   2.186 +        return result;
   2.187 +    }
   2.188  
   2.189 -   int size() {
   2.190 -      return cachePerProject.size();
   2.191 -   }
   2.192 +    int size() {
   2.193 +        return cachePerProject.size();
   2.194 +    }
   2.195  
   2.196 -   int size(final String projectName) {
   2.197 -      return cachePerProject.get(projectName).numberPlsqlObjects();
   2.198 -   }
   2.199 +    int size(final String projectName) {
   2.200 +        return cachePerProject.get(projectName).numberPlsqlObjects();
   2.201 +    }
   2.202  
   2.203 -   private String getProjectName(final Project project) {
   2.204 -      final ProjectInformation projectInformation = ProjectUtils.getInformation(project);
   2.205 -      return projectInformation.getDisplayName();
   2.206 -   }
   2.207 +    private String getProjectName(final Project project) {
   2.208 +        final ProjectInformation projectInformation = ProjectUtils.getInformation(project);
   2.209 +        return projectInformation.getDisplayName();
   2.210 +    }
   2.211  
   2.212 -   @Override
   2.213 -   public PlsqlBlockType getPlsqlType(final Project project, final String parent) {
   2.214 -      final PlsqlProjectFileCacheManager fileCache = cachePerProject.get(getProjectName(project));
   2.215 -      return fileCache.getPlsqlType(parent);
   2.216 -   }
   2.217 +    @Override
   2.218 +    public PlsqlBlockType getPlsqlType(final Project project, final String parent) {
   2.219 +        final PlsqlProjectFileCacheManager fileCache = cachePerProject.get(getProjectName(project));
   2.220 +        return fileCache.getPlsqlType(parent);
   2.221 +    }
   2.222  
   2.223 -   @Override
   2.224 -   public void addFileToCache(final Project project, final FileObject fileObject) throws IOException {
   2.225 -      if (project != null && fileObject != null) {
   2.226 -         logger.log(Level.FINE, "addFileToCache for project [{0}] with fileObject [{1}]", new Object[]{getProjectName(project), fileObject});
   2.227 -         final PlsqlProjectFileCacheManager fileCache = cachePerProject.get(getProjectName(project));
   2.228 -         if (fileCache != null) {
   2.229 -            fileCache.addFileToCache(fileObject);
   2.230 -         } else {
   2.231 -            logger.log(Level.WARNING, "PlsqlProjectFileCacheManager == null for project [{0}] with fileObject [{1}]", new Object[]{getProjectName(project), fileObject});
   2.232 -         }
   2.233 -      }
   2.234 -   }
   2.235 +    @Override
   2.236 +    public void addFileToCache(final Project project, final FileObject fileObject) throws IOException {
   2.237 +        if (project != null && fileObject != null) {
   2.238 +            logger.log(Level.FINE, "addFileToCache for project [{0}] with fileObject [{1}]", new Object[]{getProjectName(project), fileObject});
   2.239 +            final PlsqlProjectFileCacheManager fileCache = cachePerProject.get(getProjectName(project));
   2.240 +            if (fileCache != null) {
   2.241 +                fileCache.addFileToCache(fileObject);
   2.242 +            } else {
   2.243 +                logger.log(Level.WARNING, "PlsqlProjectFileCacheManager == null for project [{0}] with fileObject [{1}]", new Object[]{getProjectName(project), fileObject});
   2.244 +            }
   2.245 +        }
   2.246 +    }
   2.247  
   2.248      @Override
   2.249      public Collection<File> getAllPlsqlFiles(Project project) {
     3.1 --- a/Utilities/Oracle/src/org/netbeans/modules/plsqlsupport/db/DatabaseContentManager.java	Tue Jun 04 16:42:05 2013 +0200
     3.2 +++ b/Utilities/Oracle/src/org/netbeans/modules/plsqlsupport/db/DatabaseContentManager.java	Wed Jun 05 21:45:20 2013 +0200
     3.3 @@ -48,7 +48,6 @@
     3.4  import java.io.IOException;
     3.5  import java.io.ObjectInputStream;
     3.6  import java.io.ObjectOutputStream;
     3.7 -import java.sql.Connection;
     3.8  import java.sql.SQLException;
     3.9  import java.util.ArrayList;
    3.10  import java.util.Collection;
    3.11 @@ -62,1268 +61,1283 @@
    3.12  import org.netbeans.api.db.explorer.DatabaseConnection;
    3.13  import org.netbeans.api.progress.ProgressHandle;
    3.14  import org.netbeans.api.progress.ProgressHandleFactory;
    3.15 +import org.openide.modules.Places;
    3.16  import org.openide.util.Exceptions;
    3.17  import org.openide.util.RequestProcessor;
    3.18  
    3.19  public class DatabaseContentManager {
    3.20  
    3.21 -   private static final String cacheDir = System.getProperty("netbeans.user") + "/var/cache/plsql";
    3.22 -   private static final String sequenceCacheFile = "all_sequences.cache";
    3.23 -   private static final String tableCacheFile = "all_tables.cache";
    3.24 -   private static final String packageCacheFile = "all_packages.cache";
    3.25 -   private static final String ownerCacheFile = "all_object_owners.cache";
    3.26 -   private static final String viewCacheFile = "all_views.cache";
    3.27 -   private static final String moduleCacheFile = "all_modules.cache";
    3.28 -   private static final String luCacheFile = "all_lus.cache";
    3.29 -   private static final String enumerationCacheFile = "all_enumerations.cache";
    3.30 -   private static final String synonymCacheFile = "all_synonyms.cache";
    3.31 -   private static final String functionCacheFile = "all_functions.cache";
    3.32 -   private static final String procedureCacheFile = "all_procedures.cache";
    3.33 -   private static final String LAST_FETCH_TIME = "LFT";
    3.34 -   private static final String TABLES = "TABLES";
    3.35 -   private static final String VIEWS = "VIEWS";
    3.36 -   private static final String PACKAGES = "PKGS";
    3.37 -   private static final String PACKAGE_INFO = "PKG_INFO";
    3.38 -   private static final String SEQUENCES = "SEQ";
    3.39 -   private static final String ENUMERATIONS = "ENUMERATIONS";
    3.40 -   private static final String LUS = "LUS";
    3.41 -   private static final String VIEW_SYNONYMS = "VIEW_SYNONYMS";
    3.42 -   private static final String TABLE_SYNONYMS = "TABLE_SYNONYMS";
    3.43 -   private static final String PKG_SYNONYMS = "PKG_SYNONYMS";
    3.44 -   private static final String FUNCTIONS = "FUNCTIONS";
    3.45 -   private static final String PROCEDURES = "PROCEDURES";
    3.46 -   private static final String BEGINNING_OF_TIME = "1900/01/01:00:00:00";
    3.47 -   private static Map<String, DatabaseContentManager> instances = new HashMap<String, DatabaseContentManager>();
    3.48 -   private String directory;
    3.49 -   private String user;
    3.50 -   private String lastPackageSyncTime = BEGINNING_OF_TIME;
    3.51 -   private String lastViewSyncTime = BEGINNING_OF_TIME;
    3.52 -   private String lastTableSyncTime = BEGINNING_OF_TIME;
    3.53 -   private String lastSequenceSyncTime = BEGINNING_OF_TIME;
    3.54 -   private String lastEnumerationSyncTime = BEGINNING_OF_TIME;
    3.55 -   private String lastLUSyncTime = BEGINNING_OF_TIME;
    3.56 -   private String lastSynonymSyncTime = BEGINNING_OF_TIME;
    3.57 -   private String lastFunctionSyncTime = BEGINNING_OF_TIME;
    3.58 -   private String lastProcedureSyncTime = BEGINNING_OF_TIME;
    3.59 -   private Map<String, DatabaseObjectInfo> tableNameMap = new HashMap<String, DatabaseObjectInfo>();
    3.60 -   private Map<String, DatabaseObjectInfo> viewNameMap = new HashMap<String, DatabaseObjectInfo>();
    3.61 -   private Map<String, DatabaseObjectInfo> pkgNameMap = new HashMap<String, DatabaseObjectInfo>();
    3.62 -   private Map<String, Map<String, String>> pkgInfoMap = new HashMap<String, Map<String, String>>();
    3.63 -   private Map<String, DatabaseObjectInfo> seqMap = new HashMap<String, DatabaseObjectInfo>();
    3.64 -   private Map<String, String> ownerMap = new HashMap<String, String>();
    3.65 -   private final Set<String> schemaSet = new HashSet<String>();
    3.66 -   private Set<String> enumerationSet = new HashSet<String>();
    3.67 -   private Set<String> logicalUnitSet = new HashSet<String>();
    3.68 -   private Map<String, String> viewSynonyms = new HashMap<String, String>();
    3.69 -   private Map<String, String> tableSynonyms = new HashMap<String, String>();
    3.70 -   private Map<String, String> packageSynonyms = new HashMap<String, String>();
    3.71 -   private Map<String, String> moduleVersionMap = new HashMap<String, String>();
    3.72 -   private final Map<String, DatabaseObjectInfo> functionNameMap = new HashMap<String, DatabaseObjectInfo>();
    3.73 -   private final Map<String, DatabaseObjectInfo> procedureNameMap = new HashMap<String, DatabaseObjectInfo>();
    3.74 -   private RequestProcessor.Task updateThread = null;
    3.75 -   private static final RequestProcessor PROCESSOR = new RequestProcessor(DatabaseContentManager.class.getName());
    3.76 -   private boolean disconnecting = false;
    3.77 -   private final Object updateLock = new Object();
    3.78 -   private final List<ExceptionListener> listeners = new ArrayList<ExceptionListener>();
    3.79 +    private static final File cacheDir = Places.getCacheSubdirectory("plsql");
    3.80 +    private static final String sequenceCacheFile = "all_sequences.cache";
    3.81 +    private static final String tableCacheFile = "all_tables.cache";
    3.82 +    private static final String packageCacheFile = "all_packages.cache";
    3.83 +    private static final String ownerCacheFile = "all_object_owners.cache";
    3.84 +    private static final String viewCacheFile = "all_views.cache";
    3.85 +    private static final String moduleCacheFile = "all_modules.cache";
    3.86 +    private static final String luCacheFile = "all_lus.cache";
    3.87 +    private static final String enumerationCacheFile = "all_enumerations.cache";
    3.88 +    private static final String synonymCacheFile = "all_synonyms.cache";
    3.89 +    private static final String functionCacheFile = "all_functions.cache";
    3.90 +    private static final String procedureCacheFile = "all_procedures.cache";
    3.91 +    private static final String LAST_FETCH_TIME = "LFT";
    3.92 +    private static final String TABLES = "TABLES";
    3.93 +    private static final String VIEWS = "VIEWS";
    3.94 +    private static final String PACKAGES = "PKGS";
    3.95 +    private static final String PACKAGE_INFO = "PKG_INFO";
    3.96 +    private static final String SEQUENCES = "SEQ";
    3.97 +    private static final String ENUMERATIONS = "ENUMERATIONS";
    3.98 +    private static final String LUS = "LUS";
    3.99 +    private static final String VIEW_SYNONYMS = "VIEW_SYNONYMS";
   3.100 +    private static final String TABLE_SYNONYMS = "TABLE_SYNONYMS";
   3.101 +    private static final String PKG_SYNONYMS = "PKG_SYNONYMS";
   3.102 +    private static final String FUNCTIONS = "FUNCTIONS";
   3.103 +    private static final String PROCEDURES = "PROCEDURES";
   3.104 +    private static final String BEGINNING_OF_TIME = "1900/01/01:00:00:00";
   3.105 +    private static Map<String, DatabaseContentManager> instances = new HashMap<String, DatabaseContentManager>();
   3.106 +    private String directory;
   3.107 +    private String user;
   3.108 +    private String lastPackageSyncTime = BEGINNING_OF_TIME;
   3.109 +    private String lastViewSyncTime = BEGINNING_OF_TIME;
   3.110 +    private String lastTableSyncTime = BEGINNING_OF_TIME;
   3.111 +    private String lastSequenceSyncTime = BEGINNING_OF_TIME;
   3.112 +    private String lastEnumerationSyncTime = BEGINNING_OF_TIME;
   3.113 +    private String lastLUSyncTime = BEGINNING_OF_TIME;
   3.114 +    private String lastSynonymSyncTime = BEGINNING_OF_TIME;
   3.115 +    private String lastFunctionSyncTime = BEGINNING_OF_TIME;
   3.116 +    private String lastProcedureSyncTime = BEGINNING_OF_TIME;
   3.117 +    private Map<String, DatabaseObjectInfo> tableNameMap = new HashMap<String, DatabaseObjectInfo>();
   3.118 +    private Map<String, DatabaseObjectInfo> viewNameMap = new HashMap<String, DatabaseObjectInfo>();
   3.119 +    private Map<String, DatabaseObjectInfo> pkgNameMap = new HashMap<String, DatabaseObjectInfo>();
   3.120 +    private Map<String, Map<String, String>> pkgInfoMap = new HashMap<String, Map<String, String>>();
   3.121 +    private Map<String, DatabaseObjectInfo> seqMap = new HashMap<String, DatabaseObjectInfo>();
   3.122 +    private Map<String, String> ownerMap = new HashMap<String, String>();
   3.123 +    private final Set<String> schemaSet = new HashSet<String>();
   3.124 +    private Set<String> enumerationSet = new HashSet<String>();
   3.125 +    private Set<String> logicalUnitSet = new HashSet<String>();
   3.126 +    private Map<String, String> viewSynonyms = new HashMap<String, String>();
   3.127 +    private Map<String, String> tableSynonyms = new HashMap<String, String>();
   3.128 +    private Map<String, String> packageSynonyms = new HashMap<String, String>();
   3.129 +    private Map<String, String> moduleVersionMap = new HashMap<String, String>();
   3.130 +    private final Map<String, DatabaseObjectInfo> functionNameMap = new HashMap<String, DatabaseObjectInfo>();
   3.131 +    private final Map<String, DatabaseObjectInfo> procedureNameMap = new HashMap<String, DatabaseObjectInfo>();
   3.132 +    private RequestProcessor.Task updateThread = null;
   3.133 +    private static final RequestProcessor PROCESSOR = new RequestProcessor(DatabaseContentManager.class.getName());
   3.134 +    private boolean disconnecting = false;
   3.135 +    private final Object updateLock = new Object();
   3.136 +    private final List<ExceptionListener> listeners = new ArrayList<ExceptionListener>();
   3.137  
   3.138 -   private DatabaseContentManager(DatabaseConnection connection) {
   3.139 -      String databaseURL = connection.getDatabaseURL();
   3.140 -      int pos = connection.getDatabaseURL().lastIndexOf("@");
   3.141 -      if (pos > 0) {
   3.142 -         databaseURL = databaseURL.substring(pos + 1);
   3.143 -      }
   3.144 -      if (databaseURL.startsWith("//")) {
   3.145 -         databaseURL = databaseURL.substring(2);
   3.146 -      }
   3.147 -      databaseURL = databaseURL.replaceAll("[:/]", ".");
   3.148 -      this.user = connection.getUser().toUpperCase(Locale.ENGLISH);
   3.149 -      this.directory = cacheDir + "/" + this.user + "@" + databaseURL.toUpperCase(Locale.ENGLISH);
   3.150 -   }
   3.151 +    private DatabaseContentManager(DatabaseConnection connection) {
   3.152 +        String databaseURL = connection.getDatabaseURL();
   3.153 +        int pos = connection.getDatabaseURL().lastIndexOf("@");
   3.154 +        if (pos > 0) {
   3.155 +            databaseURL = databaseURL.substring(pos + 1);
   3.156 +        }
   3.157 +        if (databaseURL.startsWith("//")) {
   3.158 +            databaseURL = databaseURL.substring(2);
   3.159 +        }
   3.160 +        databaseURL = databaseURL.replaceAll("[:/]", ".");
   3.161 +        this.user = connection.getUser().toUpperCase(Locale.ENGLISH);
   3.162 +        this.directory = cacheDir.getPath() + "/" + this.user + "@" + databaseURL.toUpperCase(Locale.ENGLISH);
   3.163 +    }
   3.164  
   3.165 -   public static DatabaseContentManager getInstance(DatabaseConnection connection) {
   3.166 -      if (connection == null) {
   3.167 -         return null;
   3.168 -      }
   3.169 -      String key = connection.getUser() + "@" + connection.getDatabaseURL();
   3.170 -      DatabaseContentManager instance = instances.get(key);
   3.171 -      if (instance == null) {
   3.172 -         instance = new DatabaseContentManager(connection);
   3.173 -         instances.put(key, instance);
   3.174 -      }
   3.175 -      return instance;
   3.176 -   }
   3.177 +    public static DatabaseContentManager getInstance(DatabaseConnection connection) {
   3.178 +        if (connection == null) {
   3.179 +            return null;
   3.180 +        }
   3.181 +        String key = connection.getUser() + "@" + connection.getDatabaseURL();
   3.182 +        DatabaseContentManager instance = instances.get(key);
   3.183 +        if (instance == null) {
   3.184 +            instance = new DatabaseContentManager(connection);
   3.185 +            instances.put(key, instance);
   3.186 +        }
   3.187 +        return instance;
   3.188 +    }
   3.189  
   3.190 -   public void disconnectingFromDatabase() {
   3.191 -      disconnecting = true;
   3.192 -   }
   3.193 +    public void disconnectingFromDatabase() {
   3.194 +        disconnecting = true;
   3.195 +    }
   3.196  
   3.197 -   public void initializeCache(DatabaseConnectionManager connectionManager) {
   3.198 -      updateCache(connectionManager, false);
   3.199 -   }
   3.200 +    public void initializeCache(DatabaseConnectionManager connectionManager) {
   3.201 +        updateCache(connectionManager, false);
   3.202 +    }
   3.203  
   3.204 -   public void updateCache(DatabaseConnectionManager connectionManager) {
   3.205 -      updateCache(connectionManager, false);
   3.206 -   }
   3.207 +    public void updateCache(DatabaseConnectionManager connectionManager) {
   3.208 +        updateCache(connectionManager, false);
   3.209 +    }
   3.210  
   3.211 -   private void extractSchemas(Collection<String> schemas) {
   3.212 -      for (String schema : schemas) {
   3.213 -         addSchema(schema);
   3.214 -      }
   3.215 -   }
   3.216 +    private void extractSchemas(Collection<String> schemas) {
   3.217 +        for (String schema : schemas) {
   3.218 +            addSchema(schema);
   3.219 +        }
   3.220 +    }
   3.221  
   3.222 -   private void addSchema(String schema) {
   3.223 -      if (schema == null) {
   3.224 -         return;
   3.225 -      }
   3.226 -      schemaSet.add(schema);
   3.227 -   }
   3.228 +    private void addSchema(String schema) {
   3.229 +        if (schema == null) {
   3.230 +            return;
   3.231 +        }
   3.232 +        schemaSet.add(schema);
   3.233 +    }
   3.234  
   3.235 -   @SuppressWarnings("unchecked")
   3.236 -   public void updateCache(final DatabaseConnectionManager connectionManager, final boolean forceUpdate) {
   3.237 -      if (updateThread == null || updateThread.isFinished()) {
   3.238 -         updateThread = PROCESSOR.post(new Runnable() {
   3.239 +    @SuppressWarnings("unchecked")
   3.240 +    public void updateCache(final DatabaseConnectionManager connectionManager, final boolean forceUpdate) {
   3.241 +        if (updateThread == null || updateThread.isFinished()) {
   3.242 +            updateThread = PROCESSOR.post(new Runnable() {
   3.243 +                @Override
   3.244 +                public void run() {
   3.245 +                    if (ownerMap == null || ownerMap.isEmpty()) {
   3.246 +                        Map map = readMapFromFile(getCacheDir(), ownerCacheFile);
   3.247 +                        if (map != null) {
   3.248 +                            ownerMap = map;
   3.249 +                        }
   3.250 +                    }
   3.251 +                    DatabaseConnection connection = ((forceUpdate || ownerMap == null || ownerMap.isEmpty()) && connectionManager != null) ? connectionManager.getPooledDatabaseConnection(true) : null;
   3.252 +                    try {
   3.253 +                        synchronousCacheUpdate(connection, forceUpdate);
   3.254 +                        extractSchemas(ownerMap.values());
   3.255 +                    } finally {
   3.256 +                        if (connectionManager != null) {
   3.257 +                            connectionManager.releaseDatabaseConnection(connection);
   3.258 +                        }
   3.259 +                    }
   3.260 +                }
   3.261 +            });
   3.262 +        }
   3.263 +    }
   3.264  
   3.265 +    private void synchronousCacheUpdate(final DatabaseConnection connection, final boolean forceUpdate) {
   3.266 +        ProgressHandle handle = ProgressHandleFactory.createHandle("Updating database cache...");
   3.267 +        handle.start(10);
   3.268 +        try {
   3.269 +            disconnecting = false;
   3.270 +            synchronized (updateLock) {
   3.271 +                try {
   3.272 +                    int workunit = 0;
   3.273 +                    String verb = forceUpdate ? "Updating" : "Initializing";
   3.274 +                    handle.progress(verb + " package cache", workunit++);
   3.275 +                    updatePackageCache(connection, forceUpdate);
   3.276 +                    handle.progress(verb + " sequence cache", workunit++);
   3.277 +                    updateSequenceCache(connection, forceUpdate);
   3.278 +                    handle.progress(verb + " view cache", workunit++);
   3.279 +                    updateViewCache(connection, forceUpdate);
   3.280 +                    handle.progress(verb + " table cache", workunit++);
   3.281 +                    updateTableCache(connection, forceUpdate);
   3.282 +                    handle.progress(verb + " logical unit cache", workunit++);
   3.283 +                    updateLUCache(connection, forceUpdate);
   3.284 +                    handle.progress(verb + " enumeration type cache", workunit++);
   3.285 +                    updateEnumerationCache(connection, forceUpdate);
   3.286 +                    handle.progress(verb + " synonym cache", workunit++);
   3.287 +                    updateSynonymCache(connection, forceUpdate);
   3.288 +                    handle.progress(verb + " module cache", workunit++);
   3.289 +                    updateModuleCache(connection, forceUpdate);
   3.290 +                    handle.progress(verb + " function cache", workunit++);
   3.291 +                    updateFunctionCache(connection, forceUpdate);
   3.292 +                    handle.progress(verb + " procedure cache", workunit++);
   3.293 +                    updateProcedureCache(connection, forceUpdate);
   3.294 +                    handle.progress("Done", workunit++);
   3.295 +                } catch (RuntimeException e) {
   3.296 +                    //Q&D fix: if we're disconnecting from the database we will get an SQLException.
   3.297 +                    //If so ignore it, otherwise throw the exception again
   3.298 +                    if (!disconnecting) {
   3.299 +                        throw (e);
   3.300 +                    }
   3.301 +                }
   3.302 +            }
   3.303 +        } finally {
   3.304 +            handle.finish();
   3.305 +        }
   3.306 +    }
   3.307 +
   3.308 +    public String getCacheDir() {
   3.309 +        return directory;
   3.310 +    }
   3.311 +
   3.312 +    public void clearCache() {
   3.313 +        lastPackageSyncTime = BEGINNING_OF_TIME;
   3.314 +        lastViewSyncTime = BEGINNING_OF_TIME;
   3.315 +        lastTableSyncTime = BEGINNING_OF_TIME;
   3.316 +        lastSequenceSyncTime = BEGINNING_OF_TIME;
   3.317 +        lastEnumerationSyncTime = BEGINNING_OF_TIME;
   3.318 +        lastLUSyncTime = BEGINNING_OF_TIME;
   3.319 +        lastSynonymSyncTime = BEGINNING_OF_TIME;
   3.320 +        removeCacheFile(tableCacheFile);
   3.321 +        removeCacheFile(viewCacheFile);
   3.322 +        removeCacheFile(packageCacheFile);
   3.323 +        removeCacheFile(sequenceCacheFile);
   3.324 +        removeCacheFile(ownerCacheFile);
   3.325 +        removeCacheFile(enumerationCacheFile);
   3.326 +        removeCacheFile(luCacheFile);
   3.327 +        removeCacheFile(moduleCacheFile);
   3.328 +        removeCacheFile(synonymCacheFile);
   3.329 +        tableNameMap = new HashMap<String, DatabaseObjectInfo>();
   3.330 +        viewNameMap = new HashMap<String, DatabaseObjectInfo>();
   3.331 +        pkgNameMap = new HashMap<String, DatabaseObjectInfo>();
   3.332 +        pkgInfoMap = new HashMap<String, Map<String, String>>();
   3.333 +        moduleVersionMap = new HashMap<String, String>();
   3.334 +        seqMap = new HashMap<String, DatabaseObjectInfo>();
   3.335 +        ownerMap = new HashMap<String, String>();
   3.336 +        logicalUnitSet = new HashSet<String>();
   3.337 +        enumerationSet = new HashSet<String>();
   3.338 +        viewSynonyms = new HashMap<String, String>();
   3.339 +        tableSynonyms = new HashMap<String, String>();
   3.340 +        packageSynonyms = new HashMap<String, String>();
   3.341 +    }
   3.342 +
   3.343 +    private static boolean writeObjectToDisk(String dir, String file, Object obj) {
   3.344 +        FileOutputStream writer = null;
   3.345 +        ObjectOutputStream out = null;
   3.346 +        try {
   3.347 +            File test = new File(dir);
   3.348 +            if (!test.exists()) {
   3.349 +                test.mkdirs();
   3.350 +            }
   3.351 +
   3.352 +            File f = new File(dir, file);
   3.353 +            if (!f.exists()) {
   3.354 +                f.createNewFile();
   3.355 +            }
   3.356 +            writer = new FileOutputStream(f);
   3.357 +            out = new ObjectOutputStream(writer);
   3.358 +            out.writeObject(obj);
   3.359 +        } catch (IOException ex) {
   3.360 +            Exceptions.printStackTrace(ex);
   3.361 +            return false;
   3.362 +        } finally {
   3.363 +            try {
   3.364 +                if (out != null) {
   3.365 +                    out.close();
   3.366 +                }
   3.367 +                if (writer != null) {
   3.368 +                    writer.close();
   3.369 +                }
   3.370 +            } catch (IOException e) {
   3.371 +                Exceptions.printStackTrace(e);
   3.372 +            }
   3.373 +        }
   3.374 +        return true;
   3.375 +    }
   3.376 +
   3.377 +    @SuppressWarnings("unchecked")
   3.378 +    private static Map<String, String> readMapFromFile(String dir, String file) {
   3.379 +        File f = new File(dir, file);
   3.380 +        if (f.exists()) {
   3.381 +            boolean deleteFile = false;
   3.382 +            FileInputStream reader = null;
   3.383 +            {
   3.384 +                ObjectInputStream in = null;
   3.385 +                try {
   3.386 +                    reader = new FileInputStream(f);
   3.387 +                    in = new ObjectInputStream(reader);
   3.388 +                    Map map = (Map) in.readObject();
   3.389 +                    return map;
   3.390 +                } catch (IOException ex) {
   3.391 +                    Exceptions.printStackTrace(ex);
   3.392 +                } catch (ClassNotFoundException ex) {
   3.393 +                    //file currupt, try to delete the file;
   3.394 +                    deleteFile = true;
   3.395 +                } finally {
   3.396 +                    try {
   3.397 +                        if (reader != null) {
   3.398 +                            reader.close();
   3.399 +                        }
   3.400 +                        if (deleteFile) {
   3.401 +                            f.delete();
   3.402 +                        }
   3.403 +                    } catch (IOException ex) {
   3.404 +                        Exceptions.printStackTrace(ex);
   3.405 +                    }
   3.406 +                    try {
   3.407 +                        if (in != null) {
   3.408 +                            in.close();
   3.409 +                        }
   3.410 +                    } catch (IOException ex) {
   3.411 +                        Exceptions.printStackTrace(ex);
   3.412 +                    }
   3.413 +                }
   3.414 +            }
   3.415 +        }
   3.416 +        return null;
   3.417 +    }
   3.418 +
   3.419 +    private static String formatCacheFileName(String type, String name) {
   3.420 +        if (name != null) {
   3.421 +            return type + "_" + name + ".cache";
   3.422 +        }
   3.423 +        return type;
   3.424 +    }
   3.425 +
   3.426 +    private void removeCacheFiles(String[] types, String name) {
   3.427 +        for (String type : types) {
   3.428 +            removeCacheFile(formatCacheFileName(type, name));
   3.429 +        }
   3.430 +    }
   3.431 +
   3.432 +    private void removeCacheFile(String fileName) {
   3.433 +        File f = new File(getCacheDir(), fileName);
   3.434 +        if (f.exists()) {
   3.435 +            f.delete();
   3.436 +        }
   3.437 +
   3.438 +    }
   3.439 +
   3.440 +    /**
   3.441 +     * Get complete list of database tables
   3.442 +     *
   3.443 +     * @return List of all tables in the cache
   3.444 +     */
   3.445 +    public Collection<String> getAllTables() {
   3.446 +        return getAllTables(null);
   3.447 +    }
   3.448 +
   3.449 +    /**
   3.450 +     * Get complete list of database tables
   3.451 +     *
   3.452 +     * @schema Optional schema name to return objects for
   3.453 +     * @return List of all tables in the cache
   3.454 +     */
   3.455 +    public Collection<String> getAllTables(String schema) {
   3.456 +        return getAllObjects(schema, tableNameMap, tableSynonyms);
   3.457 +    }
   3.458 +
   3.459 +    /**
   3.460 +     * Get complete list of database packages
   3.461 +     *
   3.462 +     * @return List of all packages in the cache
   3.463 +     */
   3.464 +    public Collection<String> getAllPackages() {
   3.465 +        return getAllPackages(null);
   3.466 +    }
   3.467 +
   3.468 +    /**
   3.469 +     * Get complete list of database packages
   3.470 +     *
   3.471 +     * @schema Optional schema name to return objects for
   3.472 +     * @return List of all packages in the cache
   3.473 +     */
   3.474 +    public Collection<String> getAllPackages(String schema) {
   3.475 +        return getAllObjects(schema, pkgNameMap, packageSynonyms);
   3.476 +    }
   3.477 +
   3.478 +    /**
   3.479 +     * Get complete list of database views
   3.480 +     *
   3.481 +     * @return List of all views in the cache
   3.482 +     */
   3.483 +    public Collection<String> getAllViews() {
   3.484 +        return getAllViews(null);
   3.485 +    }
   3.486 +
   3.487 +    /**
   3.488 +     * Get complete list of database views
   3.489 +     *
   3.490 +     * @schema Optional schema name to return objects for
   3.491 +     * @return List of all views in the cache
   3.492 +     */
   3.493 +    public Collection<String> getAllViews(String schema) {
   3.494 +        return getAllObjects(schema, viewNameMap, viewSynonyms);
   3.495 +    }
   3.496 +
   3.497 +    /**
   3.498 +     * Get complete list of database sequences
   3.499 +     *
   3.500 +     * @return List of all sequences in the cache
   3.501 +     */
   3.502 +    public Collection<String> getAllSequences() {
   3.503 +        return getAllSequences(null);
   3.504 +    }
   3.505 +
   3.506 +    /**
   3.507 +     * Get complete list of database sequences
   3.508 +     *
   3.509 +     * @schema Optional schema name to return objects for
   3.510 +     * @return List of all sequences in the cache
   3.511 +     */
   3.512 +    public Collection<String> getAllSequences(String schema) {
   3.513 +        return getAllObjects(schema, seqMap, null);
   3.514 +    }
   3.515 +
   3.516 +    /**
   3.517 +     * Get complete list of database functions
   3.518 +     *
   3.519 +     * @return List of all functions in the cache
   3.520 +     */
   3.521 +    public Collection<String> getAllFunctions() {
   3.522 +        return getAllFunctions(null);
   3.523 +    }
   3.524 +
   3.525 +    /**
   3.526 +     * Get complete list of database functions
   3.527 +     *
   3.528 +     * @schema Optional schema name to return objects for
   3.529 +     * @return List of all functions in the cache
   3.530 +     */
   3.531 +    public Collection<String> getAllFunctions(String schema) {
   3.532 +        return getAllObjects(schema, functionNameMap, null);
   3.533 +    }
   3.534 +
   3.535 +    /**
   3.536 +     * Get complete list of database procedures
   3.537 +     *
   3.538 +     * @return List of all procedures in the cache
   3.539 +     */
   3.540 +    public Collection<String> getAllProcedures() {
   3.541 +        return getAllProcedures(null);
   3.542 +    }
   3.543 +
   3.544 +    /**
   3.545 +     * Get complete list of database functions
   3.546 +     *
   3.547 +     * @schema Optional schema name to return objects for
   3.548 +     * @return List of all functions in the cache
   3.549 +     */
   3.550 +    public Collection<String> getAllProcedures(String schema) {
   3.551 +        return getAllObjects(schema, procedureNameMap, null);
   3.552 +    }
   3.553 +
   3.554 +    private Collection<String> getAllObjects(String schema, Map<String, DatabaseObjectInfo> objectMap, Map<String, String> synonyms) {
   3.555 +        HashSet<String> result = new HashSet<String>();
   3.556 +        if (schema == null) {
   3.557 +            schema = user;
   3.558 +            if (synonyms != null) { //add synonyms if there's no owner prefix
   3.559 +                result.addAll(synonyms.keySet());
   3.560 +            }
   3.561 +        }
   3.562 +        if (!schema.startsWith("\"")) {
   3.563 +            schema = schema.toUpperCase(Locale.ENGLISH);
   3.564 +        } else if ("&AO".equals(schema)) { //IFS specific workaround for appowner prefix as used in client code
   3.565 +            schema = "IFSAPP";
   3.566 +        }
   3.567 +
   3.568 +        for (String name : objectMap.keySet()) {
   3.569 +            DatabaseObjectInfo objectInfo = objectMap.get(name);
   3.570 +            if (objectInfo.getOwner().equals(schema)) {
   3.571 +                result.add(name);
   3.572 +            }
   3.573 +        }
   3.574 +        return result;
   3.575 +    }
   3.576 +
   3.577 +    /**
   3.578 +     * Get list of database tables modified after lastFetchDate
   3.579 +     *
   3.580 +     * @return List of newly updated tables
   3.581 +     */
   3.582 +    @SuppressWarnings("unchecked")
   3.583 +    private void updateTableCache(DatabaseConnection connection, boolean forceUpdate) {
   3.584 +        ObjectCacheUpdater cacheUpdater = new ObjectCacheUpdater() {
   3.585              @Override
   3.586 -            public void run() {
   3.587 -               if (ownerMap == null || ownerMap.isEmpty()) {
   3.588 -                  Map map = readMapFromFile(getCacheDir(), ownerCacheFile);
   3.589 -                  if (map != null) {
   3.590 -                     ownerMap = map;
   3.591 -                  }
   3.592 -               }
   3.593 -               DatabaseConnection connection = ((forceUpdate || ownerMap == null || ownerMap.isEmpty()) && connectionManager != null) ? connectionManager.getPooledDatabaseConnection(true) : null;
   3.594 -               try {
   3.595 -                  synchronousCacheUpdate(connection, forceUpdate);
   3.596 -                  extractSchemas(ownerMap.values());
   3.597 -               } finally {
   3.598 -                  if (connectionManager != null) {
   3.599 -                     connectionManager.releaseDatabaseConnection(connection);
   3.600 -                  }
   3.601 -               }
   3.602 +            public void FetchObjectsFromDatabase(String lastSyncTime, List<String> objects, List<DatabaseObjectInfo> objectInfoList, DatabaseConnection connection) throws SQLException {
   3.603 +                DatabaseContentUtilities.getTableNames(lastSyncTime, objects, objectInfoList, connection.getJDBCConnection());
   3.604              }
   3.605 -         });
   3.606 -      }
   3.607 -   }
   3.608 +        };
   3.609 +        lastTableSyncTime = cacheUpdater.updateObjectCache(tableCacheFile, tableNameMap, TABLES, lastTableSyncTime, connection, forceUpdate, new String[]{TABLES});
   3.610 +    }
   3.611  
   3.612 -   private void synchronousCacheUpdate(final DatabaseConnection connection, final boolean forceUpdate) {
   3.613 -      ProgressHandle handle = ProgressHandleFactory.createHandle("Updating database cache...");
   3.614 -      handle.start(10);
   3.615 -      try {
   3.616 -         disconnecting = false;
   3.617 -         synchronized (updateLock) {
   3.618 +    /**
   3.619 +     * Get list of enumeration LUs
   3.620 +     *
   3.621 +     * @return List of enumerations
   3.622 +     */
   3.623 +    @SuppressWarnings("unchecked")
   3.624 +    private void updateSynonymCache(DatabaseConnection connection, boolean forceUpdate) {
   3.625 +        synchronized (synonymCacheFile) {
   3.626 +            if (viewSynonyms.isEmpty() && tableSynonyms.isEmpty() && packageSynonyms.isEmpty()) {
   3.627 +                Map cache = readMapFromFile(getCacheDir(), synonymCacheFile);
   3.628 +                if (cache != null) {
   3.629 +                    lastSynonymSyncTime = (String) cache.get(LAST_FETCH_TIME);
   3.630 +                    viewSynonyms = (HashMap) cache.get(VIEW_SYNONYMS);
   3.631 +                    if (viewSynonyms == null) {
   3.632 +                        viewSynonyms = new HashMap<String, String>();
   3.633 +                    }
   3.634 +                    tableSynonyms = (HashMap) cache.get(TABLE_SYNONYMS);
   3.635 +                    if (tableSynonyms == null) {
   3.636 +                        tableSynonyms = new HashMap<String, String>();
   3.637 +                    }
   3.638 +                    packageSynonyms = (HashMap) cache.get(PKG_SYNONYMS);
   3.639 +                    if (packageSynonyms == null) {
   3.640 +                        packageSynonyms = new HashMap<String, String>();
   3.641 +                    }
   3.642 +                }
   3.643 +            }
   3.644 +            if (lastSynonymSyncTime == null) {
   3.645 +                lastSynonymSyncTime = BEGINNING_OF_TIME;
   3.646 +            }
   3.647 +            if (connection != null && connection.getJDBCConnection() != null && (forceUpdate || BEGINNING_OF_TIME.equals(lastSynonymSyncTime))) {
   3.648 +                try {
   3.649 +                    Map<String, String> result = DatabaseContentUtilities.getSynonyms(connection.getJDBCConnection(), lastSynonymSyncTime);
   3.650 +                    for (Entry<String, String> entry : result.entrySet()) {
   3.651 +                        String synonym = entry.getKey().toLowerCase(Locale.ENGLISH);
   3.652 +                        String objectName = entry.getValue().toLowerCase(Locale.ENGLISH);
   3.653 +                        if (viewNameMap.containsKey(objectName)) {
   3.654 +                            viewSynonyms.put(synonym, objectName);
   3.655 +                        } else if (tableNameMap.containsKey(objectName)) {
   3.656 +                            tableSynonyms.put(synonym, objectName);
   3.657 +                        } else {
   3.658 +                            objectName = DatabaseContentUtilities.formatPlsqlName(entry.getValue());
   3.659 +                            if (pkgNameMap.containsKey(objectName)) {
   3.660 +                                packageSynonyms.put(DatabaseContentUtilities.formatPlsqlName(entry.getKey()), objectName);
   3.661 +                            }
   3.662 +                        }
   3.663 +                    }
   3.664 +
   3.665 +                    String timestamp = DatabaseContentUtilities.getCurrentTime(connection.getJDBCConnection());
   3.666 +                    Map<String, Object> cache = new HashMap<String, Object>();
   3.667 +                    cache.put(LAST_FETCH_TIME, timestamp);
   3.668 +                    cache.put(VIEW_SYNONYMS, viewSynonyms);
   3.669 +                    cache.put(TABLE_SYNONYMS, tableSynonyms);
   3.670 +                    cache.put(PKG_SYNONYMS, packageSynonyms);
   3.671 +                    writeObjectToDisk(getCacheDir(), synonymCacheFile, cache);
   3.672 +                    lastSynonymSyncTime = timestamp;
   3.673 +                } catch (SQLException ex) {
   3.674 +                    //database exception => go offline (this should only happen when the database connection is lost
   3.675 +                    //NB! This code will supress sql syntax errors
   3.676 +                    fireExceptionThrown(ex);
   3.677 +                }
   3.678 +            }
   3.679 +        }
   3.680 +    }
   3.681 +
   3.682 +    /**
   3.683 +     * Get list of enumeration LUs
   3.684 +     */
   3.685 +    @SuppressWarnings("unchecked")
   3.686 +    private void updateEnumerationCache(DatabaseConnection connection, boolean forceUpdate) {
   3.687 +        synchronized (enumerationCacheFile) {
   3.688 +            if (enumerationSet.isEmpty()) {
   3.689 +                Map cache = readMapFromFile(getCacheDir(), enumerationCacheFile);
   3.690 +                if (cache != null) {
   3.691 +                    lastEnumerationSyncTime = (String) cache.get(LAST_FETCH_TIME);
   3.692 +                    enumerationSet = (HashSet) cache.get(ENUMERATIONS);
   3.693 +                    if (enumerationSet == null) {
   3.694 +                        enumerationSet = new HashSet<String>();
   3.695 +                    }
   3.696 +                } else {
   3.697 +                    lastEnumerationSyncTime = BEGINNING_OF_TIME;
   3.698 +                }
   3.699 +            }
   3.700 +            if (lastEnumerationSyncTime == null) {
   3.701 +                lastEnumerationSyncTime = BEGINNING_OF_TIME;         //update list with latest updates from database
   3.702 +            }
   3.703 +            if (connection != null && connection.getJDBCConnection() != null && (forceUpdate || BEGINNING_OF_TIME.equals(lastPackageSyncTime))) {
   3.704 +                try {
   3.705 +                    ArrayList<String> enumerations = new ArrayList<String>();
   3.706 +                    DatabaseContentUtilities.getEnumerationTypes(lastEnumerationSyncTime, enumerations, connection);
   3.707 +                    for (int i = 0; i < enumerations.size(); i++) {
   3.708 +                        enumerationSet.add(enumerations.get(i));
   3.709 +                    }
   3.710 +                    if (enumerations.size() > 0) {
   3.711 +                        String timestamp = DatabaseContentUtilities.getCurrentTime(connection.getJDBCConnection());
   3.712 +                        Map<String, Object> cache = new HashMap<String, Object>();
   3.713 +                        cache.put(LAST_FETCH_TIME, timestamp);
   3.714 +                        cache.put(ENUMERATIONS, enumerationSet);
   3.715 +                        writeObjectToDisk(getCacheDir(), enumerationCacheFile, cache);
   3.716 +                        lastEnumerationSyncTime = timestamp;
   3.717 +                    }
   3.718 +                } catch (SQLException ex) {
   3.719 +                    //Ignore SQL Exceptions. This will happen if we use an older version of IFS Applications (before Apps7)
   3.720 +                }
   3.721 +            }
   3.722 +        }
   3.723 +    }
   3.724 +
   3.725 +    /**
   3.726 +     * Get list of "regular" LUs
   3.727 +     */
   3.728 +    @SuppressWarnings("unchecked")
   3.729 +    private void updateLUCache(DatabaseConnection connection, boolean forceUpdate) {
   3.730 +        synchronized (luCacheFile) {
   3.731 +            if (logicalUnitSet.isEmpty()) {
   3.732 +                Map cache = readMapFromFile(getCacheDir(), luCacheFile);
   3.733 +                if (cache != null) {
   3.734 +                    lastLUSyncTime = (String) cache.get(LAST_FETCH_TIME);
   3.735 +                    logicalUnitSet = (HashSet) cache.get(LUS);
   3.736 +                    if (logicalUnitSet == null) {
   3.737 +                        logicalUnitSet = new HashSet<String>();
   3.738 +                    }
   3.739 +                } else {
   3.740 +                    lastLUSyncTime = BEGINNING_OF_TIME;
   3.741 +                }
   3.742 +            }
   3.743 +            if (lastLUSyncTime == null) {
   3.744 +                lastLUSyncTime = BEGINNING_OF_TIME;
   3.745 +            }
   3.746 +            //update list with latest updates from database
   3.747 +            if (connection != null && connection.getJDBCConnection() != null && (forceUpdate || BEGINNING_OF_TIME.equals(lastPackageSyncTime))) {
   3.748 +                try {
   3.749 +                    ArrayList<String> LUs = new ArrayList<String>();
   3.750 +                    DatabaseContentUtilities.getLogicalUnits(lastLUSyncTime, LUs, connection);
   3.751 +                    for (int i = 0; i < LUs.size(); i++) {
   3.752 +                        logicalUnitSet.add(LUs.get(i));
   3.753 +                    }
   3.754 +                    if (LUs.size() > 0) {
   3.755 +                        String timestamp = DatabaseContentUtilities.getCurrentTime(connection.getJDBCConnection());
   3.756 +                        HashMap<String, Object> cache = new HashMap<String, Object>();
   3.757 +                        cache.put(LAST_FETCH_TIME, timestamp);
   3.758 +                        cache.put(LUS, logicalUnitSet);
   3.759 +                        writeObjectToDisk(getCacheDir(), luCacheFile, cache);
   3.760 +                        lastLUSyncTime = timestamp;
   3.761 +                    }
   3.762 +                } catch (SQLException ex) {
   3.763 +                    //Ignore SQL Exceptions. This will happen if we use an older version of IFS Applications (before Apps7)
   3.764 +                }
   3.765 +            }
   3.766 +        }
   3.767 +    }
   3.768 +
   3.769 +    /**
   3.770 +     * Get list of Modules installed in the database
   3.771 +     */
   3.772 +    @SuppressWarnings("unchecked")
   3.773 +    private synchronized void updateModuleCache(DatabaseConnection connection, boolean forceUpdate) {
   3.774 +        synchronized (moduleCacheFile) {
   3.775 +            Map<String, String> cachedData = readMapFromFile(getCacheDir(), moduleCacheFile);
   3.776 +            if (cachedData != null) {
   3.777 +                moduleVersionMap = cachedData;
   3.778 +            }
   3.779 +            if (connection != null && connection.getJDBCConnection() != null && (forceUpdate || cachedData == null)) {
   3.780 +                DatabaseContentUtilities.getModules(connection, moduleVersionMap);
   3.781 +                if (moduleVersionMap.size() > 0) {
   3.782 +                    writeObjectToDisk(getCacheDir(), moduleCacheFile, moduleVersionMap);
   3.783 +                }
   3.784 +            }
   3.785 +        }
   3.786 +    }
   3.787 +
   3.788 +    /**
   3.789 +     * Update the function cache with newly modified objects
   3.790 +     */
   3.791 +    @SuppressWarnings("unchecked")
   3.792 +    private void updateFunctionCache(DatabaseConnection connection, boolean forceUpdate) {
   3.793 +        ObjectCacheUpdater cacheUpdater = new ObjectCacheUpdater() {
   3.794 +            @Override
   3.795 +            public void FetchObjectsFromDatabase(String lastSyncTime, List<String> objects, List<DatabaseObjectInfo> objectInfoList, DatabaseConnection connection) throws SQLException {
   3.796 +                DatabaseContentUtilities.getFunctions(lastSyncTime, objects, objectInfoList, connection.getJDBCConnection());
   3.797 +            }
   3.798 +        };
   3.799 +        lastFunctionSyncTime = cacheUpdater.updateObjectCache(functionCacheFile, functionNameMap, FUNCTIONS, lastFunctionSyncTime, connection, forceUpdate, null);
   3.800 +    }
   3.801 +
   3.802 +    /**
   3.803 +     * Update the procedure cache with newly modified objects
   3.804 +     */
   3.805 +    @SuppressWarnings("unchecked")
   3.806 +    private void updateProcedureCache(DatabaseConnection connection, boolean forceUpdate) {
   3.807 +        ObjectCacheUpdater cacheUpdater = new ObjectCacheUpdater() {
   3.808 +            @Override
   3.809 +            public void FetchObjectsFromDatabase(String lastSyncTime, List<String> objects, List<DatabaseObjectInfo> objectInfoList, DatabaseConnection connection) throws SQLException {
   3.810 +                DatabaseContentUtilities.getProcedures(lastSyncTime, objects, objectInfoList, connection.getJDBCConnection());
   3.811 +            }
   3.812 +        };
   3.813 +        lastProcedureSyncTime = cacheUpdater.updateObjectCache(procedureCacheFile, procedureNameMap, PROCEDURES, lastProcedureSyncTime, connection, forceUpdate, null);
   3.814 +    }
   3.815 +
   3.816 +    /**
   3.817 +     * Update the view cache with newly modified objects
   3.818 +     */
   3.819 +    @SuppressWarnings("unchecked")
   3.820 +    private void updateViewCache(DatabaseConnection connection, boolean forceUpdate) {
   3.821 +        ObjectCacheUpdater cacheUpdater = new ObjectCacheUpdater() {
   3.822 +            @Override
   3.823 +            public void FetchObjectsFromDatabase(String lastSyncTime, List<String> objects, List<DatabaseObjectInfo> objectInfoList, DatabaseConnection connection) throws SQLException {
   3.824 +                DatabaseContentUtilities.getViewNames(lastSyncTime, objects, objectInfoList, connection.getJDBCConnection());
   3.825 +            }
   3.826 +        };
   3.827 +        lastViewSyncTime = cacheUpdater.updateObjectCache(viewCacheFile, viewNameMap, VIEWS, lastViewSyncTime, connection, forceUpdate, new String[]{VIEWS});
   3.828 +    }
   3.829 +
   3.830 +    /**
   3.831 +     * Get only the columns of the given table
   3.832 +     *
   3.833 +     * @param String name of view/table
   3.834 +     * @return Map
   3.835 +     */
   3.836 +    public Map<String, String> getColumnObjects(String view, DatabaseConnection databaseConnection) {
   3.837 +        if (!view.startsWith("\"")) {
   3.838 +            view = view.toLowerCase(Locale.ENGLISH);
   3.839 +        }
   3.840 +        if (isUpdateRunning()) {
   3.841 +            if (databaseConnection == null || databaseConnection.getJDBCConnection() == null) {
   3.842 +                return new HashMap<String, String>();
   3.843 +            }
   3.844              try {
   3.845 -               int workunit = 0;
   3.846 -               String verb = forceUpdate ? "Updating" : "Initializing";
   3.847 -               handle.progress(verb + " package cache", workunit++);
   3.848 -               updatePackageCache(connection, forceUpdate);
   3.849 -               handle.progress(verb + " sequence cache", workunit++);
   3.850 -               updateSequenceCache(connection, forceUpdate);
   3.851 -               handle.progress(verb + " view cache", workunit++);
   3.852 -               updateViewCache(connection, forceUpdate);
   3.853 -               handle.progress(verb + " table cache", workunit++);
   3.854 -               updateTableCache(connection, forceUpdate);
   3.855 -               handle.progress(verb + " logical unit cache", workunit++);
   3.856 -               updateLUCache(connection, forceUpdate);
   3.857 -               handle.progress(verb + " enumeration type cache", workunit++);
   3.858 -               updateEnumerationCache(connection, forceUpdate);
   3.859 -               handle.progress(verb + " synonym cache", workunit++);
   3.860 -               updateSynonymCache(connection, forceUpdate);
   3.861 -               handle.progress(verb + " module cache", workunit++);
   3.862 -               updateModuleCache(connection, forceUpdate);
   3.863 -               handle.progress(verb + " function cache", workunit++);
   3.864 -               updateFunctionCache(connection, forceUpdate);
   3.865 -               handle.progress(verb + " procedure cache", workunit++);
   3.866 -               updateProcedureCache(connection, forceUpdate);
   3.867 -               handle.progress("Done", workunit++);
   3.868 -            } catch (RuntimeException e) {
   3.869 -               //Q&D fix: if we're disconnecting from the database we will get an SQLException.
   3.870 -               //If so ignore it, otherwise throw the exception again
   3.871 -               if (!disconnecting) {
   3.872 -                  throw (e);
   3.873 -               }
   3.874 +                return DatabaseContentUtilities.getColumnNames(view, databaseConnection.getSchema(), databaseConnection.getJDBCConnection());
   3.875 +            } catch (SQLException ex) {
   3.876 +                fireExceptionThrown(ex);
   3.877 +                return new HashMap<String, String>();
   3.878              }
   3.879 -         }
   3.880 -      } finally {
   3.881 -         handle.finish();
   3.882 -      }
   3.883 -   }
   3.884 +        }
   3.885 +        synchronized (tableCacheFile) {
   3.886 +            boolean isTable = isTable(view);
   3.887 +            Map<String, DatabaseObjectInfo> map = isTable ? tableNameMap : viewNameMap;
   3.888 +            if (isTable) {
   3.889 +                if (tableSynonyms.containsKey(view)) {
   3.890 +                    view = tableSynonyms.get(view);
   3.891 +                }
   3.892 +            } else {
   3.893 +                if (viewSynonyms.containsKey(view)) {
   3.894 +                    view = viewSynonyms.get(view);
   3.895 +                }
   3.896 +            }
   3.897  
   3.898 -   public String getCacheDir() {
   3.899 -      return directory;
   3.900 -   }
   3.901  
   3.902 -   public void clearCache() {
   3.903 -      lastPackageSyncTime = BEGINNING_OF_TIME;
   3.904 -      lastViewSyncTime = BEGINNING_OF_TIME;
   3.905 -      lastTableSyncTime = BEGINNING_OF_TIME;
   3.906 -      lastSequenceSyncTime = BEGINNING_OF_TIME;
   3.907 -      lastEnumerationSyncTime = BEGINNING_OF_TIME;
   3.908 -      lastLUSyncTime = BEGINNING_OF_TIME;
   3.909 -      lastSynonymSyncTime = BEGINNING_OF_TIME;
   3.910 -      removeCacheFile(tableCacheFile);
   3.911 -      removeCacheFile(viewCacheFile);
   3.912 -      removeCacheFile(packageCacheFile);
   3.913 -      removeCacheFile(sequenceCacheFile);
   3.914 -      removeCacheFile(ownerCacheFile);
   3.915 -      removeCacheFile(enumerationCacheFile);
   3.916 -      removeCacheFile(luCacheFile);
   3.917 -      removeCacheFile(moduleCacheFile);
   3.918 -      removeCacheFile(synonymCacheFile);
   3.919 -      tableNameMap = new HashMap<String, DatabaseObjectInfo>();
   3.920 -      viewNameMap = new HashMap<String, DatabaseObjectInfo>();
   3.921 -      pkgNameMap = new HashMap<String, DatabaseObjectInfo>();
   3.922 -      pkgInfoMap = new HashMap<String, Map<String, String>>();
   3.923 -      moduleVersionMap = new HashMap<String, String>();
   3.924 -      seqMap = new HashMap<String, DatabaseObjectInfo>();
   3.925 -      ownerMap = new HashMap<String, String>();
   3.926 -      logicalUnitSet = new HashSet<String>();
   3.927 -      enumerationSet = new HashSet<String>();
   3.928 -      viewSynonyms = new HashMap<String, String>();
   3.929 -      tableSynonyms = new HashMap<String, String>();
   3.930 -      packageSynonyms = new HashMap<String, String>();
   3.931 -   }
   3.932 +            DatabaseObjectInfo objectInfo = map.get(view);
   3.933 +            if (objectInfo == null) //not a view/table
   3.934 +            {
   3.935 +                return new HashMap<String, String>();
   3.936 +            }
   3.937 +            Map<String, String> columns = objectInfo.getObjectData();
   3.938 +            if (columns == null || columns.isEmpty()) { //first look for the cache file
   3.939 +                columns = readMapFromFile(getCacheDir(), formatCacheFileName(isTable ? TABLES : VIEWS, view));
   3.940 +                try {
   3.941 +                    if (databaseConnection != null && databaseConnection.getJDBCConnection() != null) {
   3.942 +                        if (columns == null || columns.isEmpty()) {
   3.943 +                            String owner = getOwner(view);
   3.944 +                            columns = DatabaseContentUtilities.getColumnNames(view, owner, databaseConnection.getJDBCConnection());
   3.945 +                            objectInfo.setObjectData(columns);
   3.946 +                            writeObjectToDisk(getCacheDir(), formatCacheFileName(isTable ? TABLES : VIEWS, view), columns);
   3.947 +                        }
   3.948 +                    }
   3.949 +                } catch (SQLException ex) {
   3.950 +                    //database exception => go offline (this should only happen when the database connection is lost
   3.951 +                    //NB! This code will supress sql syntax errors
   3.952 +                    fireExceptionThrown(ex);
   3.953 +                }
   3.954 +                objectInfo.setObjectData(columns);
   3.955 +            }
   3.956  
   3.957 -   private static boolean writeObjectToDisk(String dir, String file, Object obj) {
   3.958 -      FileOutputStream writer = null;
   3.959 -      ObjectOutputStream out = null;
   3.960 -      try {
   3.961 -         File test = new File(dir);
   3.962 -         if (!test.exists()) {
   3.963 -            test.mkdirs();
   3.964 -         }
   3.965 +            return columns != null ? columns : new HashMap<String, String>();
   3.966 +        }
   3.967 +    }
   3.968  
   3.969 -         File f = new File(dir, file);
   3.970 -         if (!f.exists()) {
   3.971 -            f.createNewFile();
   3.972 -         }
   3.973 -         writer = new FileOutputStream(f);
   3.974 -         out = new ObjectOutputStream(writer);
   3.975 -         out.writeObject(obj);
   3.976 -      } catch (IOException ex) {
   3.977 -         Exceptions.printStackTrace(ex);
   3.978 -         return false;
   3.979 -      } finally {
   3.980 -         try {
   3.981 -            if (out != null) {
   3.982 -               out.close();
   3.983 +    /**
   3.984 +     * Update the package cache
   3.985 +     *
   3.986 +     * @return List of new/modified packages
   3.987 +     */
   3.988 +    @SuppressWarnings("unchecked")
   3.989 +    private void updatePackageCache(DatabaseConnection connection, boolean forceUpdate) {
   3.990 +        ObjectCacheUpdater cacheUpdater = new ObjectCacheUpdater() {
   3.991 +            @Override
   3.992 +            public void FetchObjectsFromDatabase(String lastSyncTime, List<String> objects, List<DatabaseObjectInfo> objectInfoList, DatabaseConnection connection) throws SQLException {
   3.993 +                DatabaseContentUtilities.getPackageNames(lastSyncTime, objects, objectInfoList, connection.getJDBCConnection());
   3.994              }
   3.995 -            if (writer != null) {
   3.996 -               writer.close();
   3.997 +        };
   3.998 +        lastPackageSyncTime = cacheUpdater.updateObjectCache(packageCacheFile, pkgNameMap, PACKAGES, lastPackageSyncTime, connection, forceUpdate, new String[]{PACKAGES, PACKAGE_INFO});
   3.999 +    }
  3.1000 +
  3.1001 +    private void writeCacheFileToDisk(String timestamp, String mapName, Map objectMap, String cacheFile) {
  3.1002 +        Map<String, Object> cache = new HashMap<String, Object>();
  3.1003 +        cache.put(LAST_FETCH_TIME, timestamp);
  3.1004 +        cache.put(mapName, objectMap);
  3.1005 +        writeObjectToDisk(getCacheDir(), cacheFile, cache);
  3.1006 +    }
  3.1007 +
  3.1008 +    /**
  3.1009 +     * Get only the functions/procedures belonging to the given owner, of the given package
  3.1010 +     *
  3.1011 +     * @param pkgName
  3.1012 +     * @return Map of methods
  3.1013 +     */
  3.1014 +    public Map<String, String> getMethodObjects(String pkgName, DatabaseConnection databaseConnection) {
  3.1015 +        if (isUpdateRunning()) {
  3.1016 +            if (databaseConnection == null || databaseConnection.getJDBCConnection() == null) {
  3.1017 +                return new HashMap<String, String>();
  3.1018              }
  3.1019 -         } catch (IOException e) {
  3.1020 -            Exceptions.printStackTrace(e);
  3.1021 -         }
  3.1022 -      }
  3.1023 -      return true;
  3.1024 -   }
  3.1025 +            try {
  3.1026 +                return DatabaseContentUtilities.getMethodNames(pkgName, databaseConnection.getSchema(), databaseConnection.getJDBCConnection());
  3.1027 +            } catch (SQLException ex) {
  3.1028 +                fireExceptionThrown(ex);
  3.1029 +                return new HashMap<String, String>();
  3.1030 +            }
  3.1031 +        }
  3.1032 +        synchronized (packageCacheFile) {
  3.1033 +            if (!pkgName.startsWith("\"")) {
  3.1034 +                pkgName = DatabaseContentUtilities.formatPlsqlName(pkgName);
  3.1035 +            }
  3.1036 +            if (packageSynonyms.containsKey(pkgName)) {
  3.1037 +                pkgName = packageSynonyms.get(pkgName);
  3.1038 +            }
  3.1039 +            DatabaseObjectInfo objectInfo = pkgNameMap.get(pkgName);
  3.1040 +            if (objectInfo == null) //not a view/table
  3.1041 +            {
  3.1042 +                return new HashMap<String, String>();
  3.1043 +            }
  3.1044 +            Map<String, String> methods = objectInfo.getObjectData();
  3.1045 +            if (methods == null || methods.isEmpty()) { //first look for the cache file
  3.1046 +                methods = readMapFromFile(getCacheDir(), formatCacheFileName(PACKAGES, pkgName));
  3.1047 +                try {
  3.1048 +                    if (databaseConnection != null && databaseConnection.getJDBCConnection() != null) {
  3.1049 +                        if (methods == null || methods.isEmpty()) { //if no cache file - fetch info from database
  3.1050 +                            String owner = getOwner(pkgName);
  3.1051 +                            methods = DatabaseContentUtilities.getMethodNames(pkgName, owner, databaseConnection.getJDBCConnection());
  3.1052 +                            writeObjectToDisk(getCacheDir(), formatCacheFileName(PACKAGES, pkgName), methods);
  3.1053 +                        }
  3.1054 +                    }
  3.1055 +                } catch (SQLException ex) {
  3.1056 +                    //database exception => go offline (this should only happen when the database connection is lost
  3.1057 +                    //NB! This code will supress sql syntax errors
  3.1058 +                    fireExceptionThrown(ex);
  3.1059 +                }
  3.1060 +                objectInfo.setObjectData(methods);
  3.1061 +            }
  3.1062 +            return methods != null ? methods : new HashMap<String, String>();
  3.1063 +        }
  3.1064 +    }
  3.1065  
  3.1066 -   @SuppressWarnings("unchecked")
  3.1067 -   private static Map<String, String> readMapFromFile(String dir, String file) {
  3.1068 -      File f = new File(dir, file);
  3.1069 -      if (f.exists()) {
  3.1070 -         boolean deleteFile = false;
  3.1071 -         FileInputStream reader = null;
  3.1072 -         {
  3.1073 -            ObjectInputStream in = null;
  3.1074 +    /**
  3.1075 +     * Get exceptions, types and constants in a given package
  3.1076 +     *
  3.1077 +     * @param pkgName
  3.1078 +     * @return Map of objects
  3.1079 +     */
  3.1080 +    public Map<String, String> getPackageMembers(String pkgName, DatabaseConnection databaseConnection) {
  3.1081 +        if (isUpdateRunning()) {
  3.1082 +            if (databaseConnection == null || databaseConnection.getJDBCConnection() == null) {
  3.1083 +                return new HashMap<String, String>();
  3.1084 +            }
  3.1085              try {
  3.1086 -               reader = new FileInputStream(f);
  3.1087 -               in = new ObjectInputStream(reader);
  3.1088 -               Map map = (Map) in.readObject();
  3.1089 -               return map;
  3.1090 -            } catch (IOException ex) {
  3.1091 -               Exceptions.printStackTrace(ex);
  3.1092 -            } catch (ClassNotFoundException ex) {
  3.1093 -               //file currupt, try to delete the file;
  3.1094 -               deleteFile = true;
  3.1095 -            } finally {
  3.1096 -               try {
  3.1097 -                  reader.close();
  3.1098 -                  if (deleteFile) {
  3.1099 -                     f.delete();
  3.1100 -                  }
  3.1101 -               } catch (IOException ex) {
  3.1102 -                  Exceptions.printStackTrace(ex);
  3.1103 -               }
  3.1104 -               try {
  3.1105 -                  in.close();
  3.1106 -               } catch (IOException ex) {
  3.1107 -                  Exceptions.printStackTrace(ex);
  3.1108 -               }
  3.1109 +                return DatabaseContentUtilities.getPackageMembers(pkgName, databaseConnection.getSchema(), databaseConnection.getJDBCConnection());
  3.1110 +            } catch (SQLException ex) {
  3.1111 +                fireExceptionThrown(ex);
  3.1112 +                return new HashMap<String, String>();
  3.1113              }
  3.1114 -         }
  3.1115 -      }
  3.1116 -      return null;
  3.1117 -   }
  3.1118 +        }
  3.1119 +        synchronized (packageCacheFile) {
  3.1120 +            if (!pkgName.startsWith("\"")) {
  3.1121 +                pkgName = DatabaseContentUtilities.formatPlsqlName(pkgName);
  3.1122 +            }
  3.1123 +            if (packageSynonyms.containsKey(pkgName)) {
  3.1124 +                pkgName = packageSynonyms.get(pkgName);
  3.1125 +            }
  3.1126 +            Map<String, String> data = pkgInfoMap.get(pkgName);
  3.1127 +            if (data == null || data.isEmpty()) { //first look for the cache file
  3.1128 +                data = readMapFromFile(getCacheDir(), formatCacheFileName(PACKAGE_INFO, pkgName));
  3.1129 +                try {
  3.1130 +                    if (data == null || data.isEmpty()) { //if no cache file - fetch info from database
  3.1131 +                        if (databaseConnection != null && databaseConnection.getJDBCConnection() != null) {
  3.1132 +                            String owner = getOwner(pkgName);
  3.1133 +                            data = DatabaseContentUtilities.getPackageMembers(pkgName, owner, databaseConnection.getJDBCConnection());
  3.1134 +                            writeObjectToDisk(getCacheDir(), formatCacheFileName(PACKAGE_INFO, pkgName), data);
  3.1135 +                        }
  3.1136 +                    }
  3.1137 +                } catch (SQLException ex) {
  3.1138 +                    //database exception => go offline (this should only happen when the database connection is lost
  3.1139 +                    //NB! This code will supress sql syntax errors
  3.1140 +                    fireExceptionThrown(ex);
  3.1141 +                }
  3.1142 +                pkgInfoMap.put(pkgName, data);
  3.1143 +            }
  3.1144 +            return data != null ? data : new HashMap<String, String>();
  3.1145 +        }
  3.1146 +    }
  3.1147  
  3.1148 -   private static String formatCacheFileName(String type, String name) {
  3.1149 -      if (name != null) {
  3.1150 -         return type + "_" + name + ".cache";
  3.1151 -      }
  3.1152 -      return type;
  3.1153 -   }
  3.1154 +    /**
  3.1155 +     * Update cache of database sequences
  3.1156 +     *
  3.1157 +     * @return List of newly updated sequences
  3.1158 +     */
  3.1159 +    @SuppressWarnings("unchecked")
  3.1160 +    private void updateSequenceCache(DatabaseConnection connection, boolean forceUpdate) {
  3.1161 +        ObjectCacheUpdater cacheUpdater = new ObjectCacheUpdater() {
  3.1162 +            @Override
  3.1163 +            public void FetchObjectsFromDatabase(String lastSyncTime, List<String> objects, List<DatabaseObjectInfo> objectInfoList, DatabaseConnection connection) throws SQLException {
  3.1164 +                DatabaseContentUtilities.getSequences(lastSyncTime, objects, objectInfoList, connection.getJDBCConnection());
  3.1165 +            }
  3.1166 +        };
  3.1167 +        lastSequenceSyncTime = cacheUpdater.updateObjectCache(sequenceCacheFile, seqMap, SEQUENCES, lastSequenceSyncTime, connection, forceUpdate, null);
  3.1168 +    }
  3.1169  
  3.1170 -   private void removeCacheFiles(String[] types, String name) {
  3.1171 -      for (String type : types) {
  3.1172 -         removeCacheFile(formatCacheFileName(type, name));
  3.1173 -      }
  3.1174 -   }
  3.1175 +    public void refreshItem(String objectName, DatabaseConnection currentConnection) {
  3.1176 +        Map<String, DatabaseObjectInfo> map = null;
  3.1177 +        String[] types = null;
  3.1178 +        String objectNameInCache = objectName.startsWith("\"") ? objectName : objectName.toLowerCase();
  3.1179 +        String camelCaseNameInCache = objectName.startsWith("\"") ? objectName : DatabaseContentUtilities.formatPlsqlName(objectName);
  3.1180 +        if (tableNameMap.containsKey(objectNameInCache)) {
  3.1181 +            map = tableNameMap;
  3.1182 +            types = new String[]{TABLES};
  3.1183 +        } else if (viewNameMap.containsKey(objectNameInCache)) {
  3.1184 +            map = viewNameMap;
  3.1185 +            types = new String[]{VIEWS};
  3.1186 +        } else if (pkgNameMap.containsKey(camelCaseNameInCache)) {
  3.1187 +            objectName = camelCaseNameInCache;
  3.1188 +            map = pkgNameMap;
  3.1189 +            if (pkgInfoMap.containsKey(camelCaseNameInCache)) {
  3.1190 +                pkgInfoMap.remove(camelCaseNameInCache);
  3.1191 +            }
  3.1192 +            types = new String[]{PACKAGES, PACKAGE_INFO};
  3.1193 +        } else if (tableSynonyms.containsKey(objectNameInCache)) {
  3.1194 +            objectName = tableSynonyms.get(objectName);
  3.1195 +            map = tableNameMap;
  3.1196 +            types = new String[]{TABLES};
  3.1197 +        } else if (viewSynonyms.containsKey(objectNameInCache)) {
  3.1198 +            objectName = viewSynonyms.get(objectName);
  3.1199 +            map = viewNameMap;
  3.1200 +            types = new String[]{VIEWS};
  3.1201 +        } else if (functionNameMap.containsKey(camelCaseNameInCache)) {
  3.1202 +            objectName = camelCaseNameInCache;
  3.1203 +            map = functionNameMap;
  3.1204 +            types = new String[]{FUNCTIONS};
  3.1205 +        } else if (procedureNameMap.containsKey(camelCaseNameInCache)) {
  3.1206 +            objectName = camelCaseNameInCache;
  3.1207 +            map = procedureNameMap;
  3.1208 +            types = new String[]{PROCEDURES};
  3.1209 +        }
  3.1210 +        if (map != null) {
  3.1211 +            removeCacheFiles(types, objectName);
  3.1212 +            DatabaseObjectInfo objectInfo = map.get(objectName);
  3.1213 +            objectInfo.setObjectData(null);
  3.1214 +        } else { //check to see if this is a newly created object (and if so add it to the cache)
  3.1215 +            if (objectName == null || objectName.length() == 0) {
  3.1216 +                //full update - run the cache update
  3.1217 +                synchronousCacheUpdate(currentConnection, true);
  3.1218 +            } else {
  3.1219 +                boolean packageFound = false;
  3.1220 +                boolean viewFound = false;
  3.1221 +                boolean tableFound = false;
  3.1222 +                boolean functionFound = false;
  3.1223 +                boolean procedureFound = false;
  3.1224 +                boolean synonymFound = false;
  3.1225 +                Map<String, DatabaseObjectInfo> databaseObjects = DatabaseContentUtilities.getObjectInfo(objectName, currentConnection, lastPackageSyncTime, lastViewSyncTime, lastTableSyncTime, lastSynonymSyncTime);
  3.1226 +                for (String actualName : databaseObjects.keySet()) {
  3.1227 +                    DatabaseObjectInfo objectInfo = databaseObjects.get(actualName);
  3.1228 +                    if (objectInfo != null && objectInfo.getObjectType() != null) {
  3.1229 +                        String objectType = objectInfo.getObjectType();
  3.1230 +                        if (DatabaseContentUtilities.isValidOracleUppercaseIdentifier(actualName)) {
  3.1231 +                            objectNameInCache = actualName.toLowerCase(Locale.ENGLISH);
  3.1232 +                        } else {
  3.1233 +                            objectNameInCache = "\"" + actualName + "\"";
  3.1234 +                        }
  3.1235 +                        addSchema(objectInfo.getOwner());
  3.1236 +                        if (objectType.startsWith("PACKAGE")) {
  3.1237 +                            objectName = objectNameInCache.startsWith("\"") ? objectNameInCache : DatabaseContentUtilities.formatPlsqlName(actualName);
  3.1238 +                            if (!isPackage(objectName, currentConnection)) {
  3.1239 +                                pkgNameMap.put(objectName, objectInfo);
  3.1240 +                                ownerMap.put(objectNameInCache, objectInfo.getOwner());
  3.1241 +                                packageFound = true;
  3.1242 +                            }
  3.1243 +                        } else if (objectType.equals("VIEW")) {
  3.1244 +                            if (!isView(objectNameInCache)) {
  3.1245 +                                viewNameMap.put(objectNameInCache, objectInfo);
  3.1246 +                                ownerMap.put(objectNameInCache, objectInfo.getOwner());
  3.1247 +                                viewFound = true;
  3.1248 +                            }
  3.1249 +                        } else if (objectType.equals("TABLE")) {
  3.1250 +                            if (!isTable(objectNameInCache)) {
  3.1251 +                                tableFound = true;
  3.1252 +                                tableNameMap.put(objectNameInCache, objectInfo);
  3.1253 +                                ownerMap.put(objectNameInCache, objectInfo.getOwner());
  3.1254 +                            }
  3.1255 +                        } else if (objectType.equals("FUNCTION")) {
  3.1256 +                            objectName = objectNameInCache.startsWith("\"") ? objectNameInCache : DatabaseContentUtilities.formatPlsqlName(actualName);
  3.1257 +                            if (!isFunction(objectName)) {
  3.1258 +                                functionFound = true;
  3.1259 +                                functionNameMap.put(objectName, objectInfo);
  3.1260 +                                ownerMap.put(objectNameInCache, objectInfo.getOwner());
  3.1261 +                            }
  3.1262 +                        } else if (objectType.equals("PROCEDURE")) {
  3.1263 +                            objectName = objectNameInCache.startsWith("\"") ? objectNameInCache : DatabaseContentUtilities.formatPlsqlName(actualName);
  3.1264 +                            if (!isProcedure(objectName)) {
  3.1265 +                                procedureFound = true;
  3.1266 +                                procedureNameMap.put(objectName, objectInfo);
  3.1267 +                                ownerMap.put(objectNameInCache, objectInfo.getOwner());
  3.1268 +                            }
  3.1269 +                        } else if (objectType.equals("SYNONYM")) {
  3.1270 +                            synonymFound = true;
  3.1271 +                            //for now just refresh all synonyms if this happens
  3.1272 +                        }
  3.1273 +                    }
  3.1274 +                }
  3.1275 +                if (packageFound) {
  3.1276 +                    writeCacheFileToDisk(lastPackageSyncTime, PACKAGES, pkgNameMap, packageCacheFile);
  3.1277 +                }
  3.1278 +                if (tableFound) {
  3.1279 +                    writeCacheFileToDisk(lastTableSyncTime, TABLES, tableNameMap, tableCacheFile);
  3.1280 +                }
  3.1281 +                if (viewFound) {
  3.1282 +                    writeCacheFileToDisk(lastViewSyncTime, VIEWS, viewNameMap, viewCacheFile);
  3.1283 +                }
  3.1284 +                if (functionFound) {
  3.1285 +                    writeCacheFileToDisk(lastFunctionSyncTime, FUNCTIONS, functionNameMap, functionCacheFile);
  3.1286 +                }
  3.1287 +                if (procedureFound) {
  3.1288 +                    writeCacheFileToDisk(lastProcedureSyncTime, PROCEDURES, procedureNameMap, procedureCacheFile);
  3.1289 +                }
  3.1290 +                if (packageFound || tableFound || viewFound || procedureFound || functionFound) {
  3.1291 +                    writeObjectToDisk(getCacheDir(), ownerCacheFile, ownerMap);
  3.1292 +                }
  3.1293 +                if (synonymFound) {
  3.1294 +                    updateSynonymCache(currentConnection, true);
  3.1295 +                }
  3.1296 +            }
  3.1297 +        }
  3.1298 +    }
  3.1299  
  3.1300 -   private void removeCacheFile(String fileName) {
  3.1301 -      File f = new File(getCacheDir(), fileName);
  3.1302 -      if (f.exists()) {
  3.1303 -         f.delete();
  3.1304 -      }
  3.1305 +    public boolean isTable(String objectName) {
  3.1306 +        if (objectName == null) {
  3.1307 +            return false;
  3.1308 +        }
  3.1309 +        if (!objectName.startsWith("\"")) {
  3.1310 +            objectName = objectName.toLowerCase(Locale.ENGLISH);
  3.1311 +        }
  3.1312 +        return tableNameMap.containsKey(objectName) || tableSynonyms.containsKey(objectName);
  3.1313 +    }
  3.1314  
  3.1315 -   }
  3.1316 +    public boolean isView(String objectName) {
  3.1317 +        if (objectName == null) {
  3.1318 +            return false;
  3.1319 +        }
  3.1320 +        if (!objectName.startsWith("\"")) {
  3.1321 +            objectName = objectName.toLowerCase(Locale.ENGLISH);
  3.1322 +        }
  3.1323 +        return viewNameMap.containsKey(objectName) || viewSynonyms.containsKey(objectName);
  3.1324 +    }
  3.1325  
  3.1326 -   /**
  3.1327 -    * Get complete list of database tables
  3.1328 -    * @return List of all tables in the cache
  3.1329 -    */
  3.1330 -   public Collection<String> getAllTables() {
  3.1331 -      return getAllTables(null);
  3.1332 -   }
  3.1333 +    public boolean isViewSynonym(String objectName) {
  3.1334 +        if (objectName == null) {
  3.1335 +            return false;
  3.1336 +        }
  3.1337 +        return viewSynonyms.containsKey(objectName.toLowerCase(Locale.ENGLISH));
  3.1338 +    }
  3.1339  
  3.1340 -   /**
  3.1341 -    * Get complete list of database tables
  3.1342 -    * @schema Optional schema name to return objects for
  3.1343 -    * @return List of all tables in the cache
  3.1344 -    */
  3.1345 -   public Collection<String> getAllTables(String schema) {
  3.1346 -      return getAllObjects(schema, tableNameMap, tableSynonyms);
  3.1347 -   }
  3.1348 +    public String getViewForSynonym(String objectName) {
  3.1349 +        if (objectName == null) {
  3.1350 +            return null;
  3.1351 +        }
  3.1352 +        if (!objectName.startsWith("\"")) {
  3.1353 +            objectName = objectName.toLowerCase(Locale.ENGLISH);
  3.1354 +        }
  3.1355 +        return viewSynonyms.get(objectName);
  3.1356 +    }
  3.1357  
  3.1358 -   /**
  3.1359 -    * Get complete list of database packages
  3.1360 -    * @return List of all packages in the cache
  3.1361 -    */
  3.1362 -   public Collection<String> getAllPackages() {
  3.1363 -      return getAllPackages(null);
  3.1364 -   }
  3.1365 +    public boolean isTableSynonym(String objectName) {
  3.1366 +        if (objectName == null) {
  3.1367 +            return false;
  3.1368 +        }
  3.1369 +        if (!objectName.startsWith("\"")) {
  3.1370 +            objectName = objectName.toLowerCase(Locale.ENGLISH);
  3.1371 +        }
  3.1372 +        return tableSynonyms.containsKey(objectName);
  3.1373 +    }
  3.1374  
  3.1375 -   /**
  3.1376 -    * Get complete list of database packages
  3.1377 -    * @schema Optional schema name to return objects for
  3.1378 -    * @return List of all packages in the cache
  3.1379 -    */
  3.1380 -   public Collection<String> getAllPackages(String schema) {
  3.1381 -      return getAllObjects(schema, pkgNameMap, packageSynonyms);
  3.1382 -   }
  3.1383 +    public String getTableForSynonym(String objectName) {
  3.1384 +        if (objectName == null) {
  3.1385 +            return null;
  3.1386 +        }
  3.1387 +        if (!objectName.startsWith("\"")) {
  3.1388 +            objectName = objectName.toLowerCase(Locale.ENGLISH);
  3.1389 +        }
  3.1390 +        return tableSynonyms.get(objectName);
  3.1391 +    }
  3.1392  
  3.1393 -   /**
  3.1394 -    * Get complete list of database views
  3.1395 -    * @return List of all views in the cache
  3.1396 -    */
  3.1397 -   public Collection<String> getAllViews() {
  3.1398 -      return getAllViews(null);
  3.1399 -   }
  3.1400 +    public boolean isPackageSynonym(String objectName) {
  3.1401 +        if (objectName == null) {
  3.1402 +            return false;
  3.1403 +        }
  3.1404 +        if (!objectName.startsWith("\"")) {
  3.1405 +            objectName = DatabaseContentUtilities.formatPlsqlName(objectName);
  3.1406 +        }
  3.1407 +        return packageSynonyms.containsKey(objectName);
  3.1408 +    }
  3.1409  
  3.1410 -   /**
  3.1411 -    * Get complete list of database views
  3.1412 -    * @schema Optional schema name to return objects for
  3.1413 -    * @return List of all views in the cache
  3.1414 -    */
  3.1415 -   public Collection<String> getAllViews(String schema) {
  3.1416 -      return getAllObjects(schema, viewNameMap, viewSynonyms);
  3.1417 -   }
  3.1418 +    public String getPackageForSynonym(String objectName) {
  3.1419 +        if (objectName == null) {
  3.1420 +            return null;
  3.1421 +        }
  3.1422 +        if (!objectName.startsWith("\"")) {
  3.1423 +            objectName = DatabaseContentUtilities.formatPlsqlName(objectName);
  3.1424 +        }
  3.1425 +        return packageSynonyms.get(objectName);
  3.1426 +    }
  3.1427  
  3.1428 -   /**
  3.1429 -    * Get complete list of database sequences
  3.1430 -    * @return List of all sequences in the cache
  3.1431 -    */
  3.1432 -   public Collection<String> getAllSequences() {
  3.1433 -      return getAllSequences(null);
  3.1434 -   }
  3.1435 +    public boolean isPackage(String objectName, DatabaseConnection currentConnection) {
  3.1436 +        if (objectName == null) {
  3.1437 +            return false;
  3.1438 +        }
  3.1439 +        if (!objectName.startsWith("\"")) {
  3.1440 +            objectName = DatabaseContentUtilities.formatPlsqlName(objectName);
  3.1441 +        }
  3.1442 +        return pkgNameMap.containsKey(objectName) || packageSynonyms.containsKey(objectName);
  3.1443 +    }
  3.1444  
  3.1445 -   /**
  3.1446 -    * Get complete list of database sequences
  3.1447 -    * @schema Optional schema name to return objects for
  3.1448 -    * @return List of all sequences in the cache
  3.1449 -    */
  3.1450 -   public Collection<String> getAllSequences(String schema) {
  3.1451 -      return getAllObjects(schema, seqMap, null);
  3.1452 -   }
  3.1453 +    public boolean isLogicalUnit(String objectName) {
  3.1454 +        if (objectName == null) {
  3.1455 +            return false;
  3.1456 +        }
  3.1457 +        return logicalUnitSet != null && logicalUnitSet.contains(objectName);
  3.1458 +    }
  3.1459  
  3.1460 -   /**
  3.1461 -    * Get complete list of database functions
  3.1462 -    * @return List of all functions in the cache
  3.1463 -    */
  3.1464 -   public Collection<String> getAllFunctions() {
  3.1465 -      return getAllFunctions(null);
  3.1466 -   }
  3.1467 +    public boolean isEnumerationType(String objectName) {
  3.1468 +        if (objectName == null) {
  3.1469 +            return false;
  3.1470 +        }
  3.1471 +        return enumerationSet != null && enumerationSet.contains(objectName);
  3.1472 +    }
  3.1473  
  3.1474 -   /**
  3.1475 -    * Get complete list of database functions
  3.1476 -    * @schema Optional schema name to return objects for
  3.1477 -    * @return List of all functions in the cache
  3.1478 -    */
  3.1479 -   public Collection<String> getAllFunctions(String schema) {
  3.1480 -      return getAllObjects(schema, functionNameMap, null);
  3.1481 -   }
  3.1482 +    public boolean isSequence(String objectName) {
  3.1483 +        if (objectName == null) {
  3.1484 +            return false;
  3.1485 +        }
  3.1486 +        if (!objectName.startsWith("\"")) {
  3.1487 +            objectName = objectName.toLowerCase(Locale.ENGLISH);
  3.1488 +        }
  3.1489 +        return this.seqMap.containsKey(objectName);
  3.1490 +    }
  3.1491  
  3.1492 -   /**
  3.1493 -    * Get complete list of database procedures
  3.1494 -    * @return List of all procedures in the cache
  3.1495 -    */
  3.1496 -   public Collection<String> getAllProcedures() {
  3.1497 -      return getAllProcedures(null);
  3.1498 -   }
  3.1499 +    public boolean isFunction(String objectName) {
  3.1500 +        if (objectName == null) {
  3.1501 +            return false;
  3.1502 +        }
  3.1503 +        if (!objectName.startsWith("\"")) {
  3.1504 +            objectName = DatabaseContentUtilities.formatPlsqlName(objectName);
  3.1505 +        }
  3.1506 +        return this.functionNameMap.containsKey(objectName);
  3.1507 +    }
  3.1508  
  3.1509 -   /**
  3.1510 -    * Get complete list of database functions
  3.1511 -    * @schema Optional schema name to return objects for
  3.1512 -    * @return List of all functions in the cache
  3.1513 -    */
  3.1514 -   public Collection<String> getAllProcedures(String schema) {
  3.1515 -      return getAllObjects(schema, procedureNameMap, null);
  3.1516 -   }
  3.1517 +    public boolean isProcedure(String objectName) {
  3.1518 +        if (objectName == null) {
  3.1519 +            return false;
  3.1520 +        }
  3.1521 +        if (!objectName.startsWith("\"")) {
  3.1522 +            objectName = DatabaseContentUtilities.formatPlsqlName(objectName);
  3.1523 +        }
  3.1524 +        return this.procedureNameMap.containsKey(objectName);
  3.1525 +    }
  3.1526  
  3.1527 -   private Collection<String> getAllObjects(String schema, Map<String, DatabaseObjectInfo> objectMap, Map<String, String> synonyms) {
  3.1528 -      HashSet<String> result = new HashSet<String>();
  3.1529 -      if (schema == null) {
  3.1530 -         schema = user;
  3.1531 -         if (synonyms != null) { //add synonyms if there's no owner prefix
  3.1532 -            result.addAll(synonyms.keySet());
  3.1533 -         }
  3.1534 -      }
  3.1535 -      if (!schema.startsWith("\"")) {
  3.1536 -         schema = schema.toUpperCase(Locale.ENGLISH);
  3.1537 -      } else if ("&AO".equals(schema)) { //IFS specific workaround for appowner prefix as used in client code
  3.1538 -         schema = "IFSAPP";
  3.1539 -      }
  3.1540 +    public boolean isSchema(String objectName) {
  3.1541 +        if (objectName == null) {
  3.1542 +            return false;
  3.1543 +        }
  3.1544 +        //IFS specific workaround for appowner prefix as used in client code
  3.1545 +        if ("&AO".equals(objectName)) {
  3.1546 +            objectName = "IFSAPP";
  3.1547 +        }
  3.1548 +        if (!objectName.startsWith("\"")) {
  3.1549 +            objectName = objectName.toUpperCase(Locale.ENGLISH);
  3.1550 +        }
  3.1551 +        return schemaSet.contains(objectName);
  3.1552 +    }
  3.1553  
  3.1554 -      for (String name : objectMap.keySet()) {
  3.1555 -         DatabaseObjectInfo objectInfo = objectMap.get(name);
  3.1556 -         if (objectInfo.getOwner().equals(schema)) {
  3.1557 -            result.add(name);
  3.1558 -         }
  3.1559 -      }
  3.1560 -      return result;
  3.1561 -   }
  3.1562 +    public Set<String> listLogicalUnits() {
  3.1563 +        return logicalUnitSet;
  3.1564 +    }
  3.1565  
  3.1566 -   /**
  3.1567 -    * Get list of database tables modified after lastFetchDate
  3.1568 -    * @return List of newly updated tables
  3.1569 -    */
  3.1570 -   @SuppressWarnings("unchecked")
  3.1571 -   private void updateTableCache(DatabaseConnection connection, boolean forceUpdate) {
  3.1572 -      ObjectCacheUpdater cacheUpdater = new ObjectCacheUpdater() {
  3.1573 +    public Set<String> listEnumerationTypes() {
  3.1574 +        return enumerationSet;
  3.1575 +    }
  3.1576  
  3.1577 -         @Override
  3.1578 -         public void FetchObjectsFromDatabase(String lastSyncTime, List<String> objects, List<DatabaseObjectInfo> objectInfoList, DatabaseConnection connection) throws SQLException {
  3.1579 -            DatabaseContentUtilities.getTableNames(lastSyncTime, objects, objectInfoList, connection.getJDBCConnection());
  3.1580 -         }
  3.1581 -      };
  3.1582 -      lastTableSyncTime = cacheUpdater.updateObjectCache(tableCacheFile, tableNameMap, TABLES, lastTableSyncTime, connection, forceUpdate, new String[]{TABLES});
  3.1583 -   }
  3.1584 +    public DatabaseObjectInfo getViewInfo(String viewName, DatabaseConnection databaseConnection) {
  3.1585 +        if (!updateThread.isFinished()) {
  3.1586 +            return DatabaseContentUtilities.getViewInfo(viewName, databaseConnection);
  3.1587 +        }
  3.1588 +        return viewNameMap.get(viewName.toLowerCase(Locale.ENGLISH));
  3.1589 +    }
  3.1590  
  3.1591 -   /**
  3.1592 -    * Get list of enumeration LUs
  3.1593 -    * @return List of enumerations
  3.1594 -    */
  3.1595 -   @SuppressWarnings("unchecked")
  3.1596 -   private void updateSynonymCache(DatabaseConnection connection, boolean forceUpdate) {
  3.1597 -      synchronized (synonymCacheFile) {
  3.1598 -         if (viewSynonyms.isEmpty() && tableSynonyms.isEmpty() && packageSynonyms.isEmpty()) {
  3.1599 -            Map cache = readMapFromFile(getCacheDir(), synonymCacheFile);
  3.1600 -            if (cache != null) {
  3.1601 -               lastSynonymSyncTime = (String) cache.get(LAST_FETCH_TIME);
  3.1602 -               viewSynonyms = (HashMap) cache.get(VIEW_SYNONYMS);
  3.1603 -               if (viewSynonyms == null) {
  3.1604 -                  viewSynonyms = new HashMap<String, String>();
  3.1605 -               }
  3.1606 -               tableSynonyms = (HashMap) cache.get(TABLE_SYNONYMS);
  3.1607 -               if (tableSynonyms == null) {
  3.1608 -                  tableSynonyms = new HashMap<String, String>();
  3.1609 -               }
  3.1610 -               packageSynonyms = (HashMap) cache.get(PKG_SYNONYMS);
  3.1611 -               if (packageSynonyms == null) {
  3.1612 -                  packageSynonyms = new HashMap<String, String>();
  3.1613 -               }
  3.1614 +    public DatabaseObjectInfo getPackageInfo(String pkgName, DatabaseConnection databaseConnection) {
  3.1615 +        DatabaseObjectInfo info = pkgNameMap.get(DatabaseContentUtilities.formatPlsqlName(pkgName));
  3.1616 +        if ((info == null || info.getLuName() == null) && databaseConnection != null) { //data not cached - fetched from the database
  3.1617 +            if (info == null) {
  3.1618 +                info = new DatabaseObjectInfo(databaseConnection.getSchema());
  3.1619              }
  3.1620 -         }
  3.1621 -         if (lastSynonymSyncTime == null) {
  3.1622 -            lastSynonymSyncTime = BEGINNING_OF_TIME;
  3.1623 -         }
  3.1624 -         if (connection != null && connection.getJDBCConnection() != null && (forceUpdate || BEGINNING_OF_TIME.equals(lastSynonymSyncTime))) {
  3.1625 -            try {
  3.1626 -               Map<String, String> result = DatabaseContentUtilities.getSynonyms(connection.getJDBCConnection(), lastSynonymSyncTime);
  3.1627 -               for (Entry<String, String> entry : result.entrySet()) {
  3.1628 -                  String synonym = entry.getKey().toLowerCase(Locale.ENGLISH);
  3.1629 -                  String objectName = entry.getValue().toLowerCase(Locale.ENGLISH);
  3.1630 -                  if (viewNameMap.containsKey(objectName)) {
  3.1631 -                     viewSynonyms.put(synonym, objectName);
  3.1632 -                  } else if (tableNameMap.containsKey(objectName)) {
  3.1633 -                     tableSynonyms.put(synonym, objectName);
  3.1634 -                  } else {
  3.1635 -                     objectName = DatabaseContentUtilities.formatPlsqlName(entry.getValue());
  3.1636 -                     if (pkgNameMap.containsKey(objectName)) {
  3.1637 -                        packageSynonyms.put(DatabaseContentUtilities.formatPlsqlName(entry.getKey()), objectName);
  3.1638 -                     }
  3.1639 -                  }
  3.1640 -               }
  3.1641 +            DatabaseContentUtilities.getMetaDataForPackage(databaseConnection.getJDBCConnection(), pkgName, info);
  3.1642 +        }
  3.1643 +        return info;
  3.1644 +    }
  3.1645  
  3.1646 -               String timestamp = DatabaseContentUtilities.getCurrentTime(connection.getJDBCConnection());
  3.1647 -               Map<String, Object> cache = new HashMap<String, Object>();
  3.1648 -               cache.put(LAST_FETCH_TIME, timestamp);
  3.1649 -               cache.put(VIEW_SYNONYMS, viewSynonyms);
  3.1650 -               cache.put(TABLE_SYNONYMS, tableSynonyms);
  3.1651 -               cache.put(PKG_SYNONYMS, packageSynonyms);
  3.1652 -               writeObjectToDisk(getCacheDir(), synonymCacheFile, cache);
  3.1653 -               lastSynonymSyncTime = timestamp;
  3.1654 -            } catch (SQLException ex) {
  3.1655 -               //database exception => go offline (this should only happen when the database connection is lost
  3.1656 -               //NB! This code will supress sql syntax errors
  3.1657 -               fireExceptionThrown(ex);
  3.1658 +    public String getModuleVersion(String moduleName) {
  3.1659 +        return moduleVersionMap.get(moduleName.toLowerCase(Locale.ENGLISH));
  3.1660 +    }
  3.1661 +
  3.1662 +    public String getOwner(String objectName) {
  3.1663 +        String owner = ownerMap.get(objectName.toLowerCase(Locale.ENGLISH));
  3.1664 +        return (owner == null ? "" : owner);
  3.1665 +    }
  3.1666 +
  3.1667 +    public String getLastPackageSyncTime() {
  3.1668 +        return lastPackageSyncTime;
  3.1669 +    }
  3.1670 +
  3.1671 +    public String getLastTableSyncTime() {
  3.1672 +        return lastTableSyncTime;
  3.1673 +    }
  3.1674 +
  3.1675 +    public String getLastViewSyncTime() {
  3.1676 +        return lastViewSyncTime;
  3.1677 +    }
  3.1678 +
  3.1679 +    public boolean isUpdateRunning() {
  3.1680 +        return (updateThread != null && !updateThread.isFinished());
  3.1681 +    }
  3.1682 +
  3.1683 +    public void addExceptionListener(ExceptionListener listener) {
  3.1684 +        listeners.add(listener);
  3.1685 +    }
  3.1686 +
  3.1687 +    public void removeExceptionListener(ExceptionListener listener) {
  3.1688 +        listeners.remove(listener);
  3.1689 +    }
  3.1690 +
  3.1691 +    private void fireExceptionThrown(Exception e) {
  3.1692 +        for (ExceptionListener listener : listeners) {
  3.1693 +            listener.exceptionThrown(e);
  3.1694 +        }
  3.1695 +    }
  3.1696 +
  3.1697 +    public String getFndbasVersion() {
  3.1698 +        return getModuleVersion("fndbas");
  3.1699 +    }
  3.1700 +
  3.1701 +    private abstract class ObjectCacheUpdater {
  3.1702 +
  3.1703 +        public String updateObjectCache(String fileName, Map objectMap, String cacheEntryName, String lastSyncTime, DatabaseConnection connection, boolean forceUpdate, String[] detailFileTypes) {
  3.1704 +            synchronized (fileName) {
  3.1705 +                if (objectMap.isEmpty()) {
  3.1706 +                    Map cache = readMapFromFile(getCacheDir(), fileName);
  3.1707 +                    if (cache != null) {
  3.1708 +                        lastSyncTime = (String) cache.get(LAST_FETCH_TIME);
  3.1709 +                        Map tempMap = (Map) cache.get(cacheEntryName);
  3.1710 +                        if (tempMap != null) {
  3.1711 +                            objectMap.putAll(tempMap);
  3.1712 +                        }
  3.1713 +                    } else {
  3.1714 +                        lastSyncTime = BEGINNING_OF_TIME;
  3.1715 +                    }
  3.1716 +                }
  3.1717 +                if (lastSyncTime == null) {
  3.1718 +                    lastSyncTime = BEGINNING_OF_TIME; //update list with latest updates from database
  3.1719 +                }
  3.1720 +                if (connection != null && connection.getJDBCConnection() != null && (forceUpdate || BEGINNING_OF_TIME.equals(lastSyncTime))) {
  3.1721 +                    try {
  3.1722 +                        List<String> objects = new ArrayList<String>();
  3.1723 +                        List<DatabaseObjectInfo> objectInfoList = new ArrayList<DatabaseObjectInfo>();
  3.1724 +                        FetchObjectsFromDatabase(lastSyncTime, objects, objectInfoList, connection);
  3.1725 +                        for (int i = 0; i < objects.size(); i++) {
  3.1726 +                            String name = objects.get(i);
  3.1727 +                            if (detailFileTypes != null) {
  3.1728 +                                removeCacheFiles(detailFileTypes, name);
  3.1729 +                            }
  3.1730 +                            DatabaseObjectInfo info = objectInfoList.isEmpty() ? null : objectInfoList.get(i);
  3.1731 +                            if (info != null) {
  3.1732 +                                ownerMap.put(name.toLowerCase(Locale.ENGLISH), info.getOwner());
  3.1733 +                            }
  3.1734 +                            objectMap.put(name, info);
  3.1735 +                        }
  3.1736 +                        if (objects.size() > 0) {
  3.1737 +                            String timestamp = DatabaseContentUtilities.getCurrentTime(connection.getJDBCConnection());
  3.1738 +                            writeCacheFileToDisk(timestamp, cacheEntryName, objectMap, fileName);
  3.1739 +                            if (!objectInfoList.isEmpty()) {
  3.1740 +                                writeObjectToDisk(getCacheDir(), ownerCacheFile, ownerMap);
  3.1741 +                            }
  3.1742 +                            lastSyncTime = timestamp;
  3.1743 +                        }
  3.1744 +                    } catch (SQLException ex) {
  3.1745 +                        //database exception => go offline (this should only happen when the database connection is lost
  3.1746 +                        //NB! This code will supress sql syntax errors
  3.1747 +                        fireExceptionThrown(ex);
  3.1748 +                    }
  3.1749 +                }
  3.1750              }
  3.1751 -         }
  3.1752 -      }
  3.1753 -   }
  3.1754 +            return lastSyncTime;
  3.1755 +        }
  3.1756  
  3.1757 -   /**
  3.1758 -    * Get list of enumeration LUs
  3.1759 -    */
  3.1760 -   @SuppressWarnings("unchecked")
  3.1761 -   private void updateEnumerationCache(DatabaseConnection connection, boolean forceUpdate) {
  3.1762 -      synchronized (enumerationCacheFile) {
  3.1763 -         if (enumerationSet.isEmpty()) {
  3.1764 -            Map cache = readMapFromFile(getCacheDir(), enumerationCacheFile);
  3.1765 -            if (cache != null) {
  3.1766 -               lastEnumerationSyncTime = (String) cache.get(LAST_FETCH_TIME);
  3.1767 -               enumerationSet = (HashSet) cache.get(ENUMERATIONS);
  3.1768 -               if (enumerationSet == null) {
  3.1769 -                  enumerationSet = new HashSet<String>();
  3.1770 -               }
  3.1771 -            } else {
  3.1772 -               lastEnumerationSyncTime = BEGINNING_OF_TIME;
  3.1773 -            }
  3.1774 -         }
  3.1775 -         if (lastEnumerationSyncTime == null) {
  3.1776 -            lastEnumerationSyncTime = BEGINNING_OF_TIME;         //update list with latest updates from database
  3.1777 -         }
  3.1778 -         if (connection != null && connection.getJDBCConnection() != null && (forceUpdate || BEGINNING_OF_TIME.equals(lastPackageSyncTime))) {
  3.1779 -            try {
  3.1780 -               ArrayList<String> enumerations = new ArrayList<String>();
  3.1781 -               DatabaseContentUtilities.getEnumerationTypes(lastEnumerationSyncTime, enumerations, connection);
  3.1782 -               for (int i = 0; i < enumerations.size(); i++) {
  3.1783 -                  enumerationSet.add(enumerations.get(i));
  3.1784 -               }
  3.1785 -               if (enumerations.size() > 0) {
  3.1786 -                  String timestamp = DatabaseContentUtilities.getCurrentTime(connection.getJDBCConnection());
  3.1787 -                  Map<String, Object> cache = new HashMap<String, Object>();
  3.1788 -                  cache.put(LAST_FETCH_TIME, timestamp);
  3.1789 -                  cache.put(ENUMERATIONS, enumerationSet);
  3.1790 -                  writeObjectToDisk(getCacheDir(), enumerationCacheFile, cache);
  3.1791 -                  lastEnumerationSyncTime = timestamp;
  3.1792 -               }
  3.1793 -            } catch (SQLException ex) {
  3.1794 -               //Ignore SQL Exceptions. This will happen if we use an older version of IFS Applications (before Apps7)
  3.1795 -            }
  3.1796 -         }
  3.1797 -      }
  3.1798 -   }
  3.1799 -
  3.1800 -   /**
  3.1801 -    * Get list of "regular" LUs
  3.1802 -    */
  3.1803 -   @SuppressWarnings("unchecked")
  3.1804 -   private void updateLUCache(DatabaseConnection connection, boolean forceUpdate) {
  3.1805 -      synchronized (luCacheFile) {
  3.1806 -         if (logicalUnitSet.isEmpty()) {
  3.1807 -            Map cache = readMapFromFile(getCacheDir(), luCacheFile);
  3.1808 -            if (cache != null) {
  3.1809 -               lastLUSyncTime = (String) cache.get(LAST_FETCH_TIME);
  3.1810 -               logicalUnitSet = (HashSet) cache.get(LUS);
  3.1811 -               if (logicalUnitSet == null) {
  3.1812 -                  logicalUnitSet = new HashSet<String>();
  3.1813 -               }
  3.1814 -            } else {
  3.1815 -               lastLUSyncTime = BEGINNING_OF_TIME;
  3.1816 -            }
  3.1817 -         }
  3.1818 -         if (lastLUSyncTime == null) {
  3.1819 -            lastLUSyncTime = BEGINNING_OF_TIME;
  3.1820 -         }
  3.1821 -         //update list with latest updates from database
  3.1822 -         if (connection != null && connection.getJDBCConnection() != null && (forceUpdate || BEGINNING_OF_TIME.equals(lastPackageSyncTime))) {
  3.1823 -            try {
  3.1824 -               ArrayList<String> LUs = new ArrayList<String>();
  3.1825 -               DatabaseContentUtilities.getLogicalUnits(lastLUSyncTime, LUs, connection);
  3.1826 -               for (int i = 0; i < LUs.size(); i++) {
  3.1827 -                  logicalUnitSet.add(LUs.get(i));
  3.1828 -               }
  3.1829 -               if (LUs.size() > 0) {
  3.1830 -                  String timestamp = DatabaseContentUtilities.getCurrentTime(connection.getJDBCConnection());
  3.1831 -                  HashMap<String, Object> cache = new HashMap<String, Object>();
  3.1832 -                  cache.put(LAST_FETCH_TIME, timestamp);
  3.1833 -                  cache.put(LUS, logicalUnitSet);
  3.1834 -                  writeObjectToDisk(getCacheDir(), luCacheFile, cache);
  3.1835 -                  lastLUSyncTime = timestamp;
  3.1836 -               }
  3.1837 -            } catch (SQLException ex) {
  3.1838 -               //Ignore SQL Exceptions. This will happen if we use an older version of IFS Applications (before Apps7)
  3.1839 -            }
  3.1840 -         }
  3.1841 -      }
  3.1842 -   }
  3.1843 -
  3.1844 -   /**
  3.1845 -    * Get list of Modules installed in the database
  3.1846 -    */
  3.1847 -   @SuppressWarnings("unchecked")
  3.1848 -   private synchronized void updateModuleCache(DatabaseConnection connection, boolean forceUpdate) {
  3.1849 -      synchronized (moduleCacheFile) {
  3.1850 -         Map<String, String> cachedData = readMapFromFile(getCacheDir(), moduleCacheFile);
  3.1851 -         if (cachedData != null) {
  3.1852 -            moduleVersionMap = cachedData;
  3.1853 -         }
  3.1854 -         if (connection != null && connection.getJDBCConnection() != null && (forceUpdate || cachedData == null)) {
  3.1855 -            DatabaseContentUtilities.getModules(connection, moduleVersionMap);
  3.1856 -            if (moduleVersionMap.size() > 0) {
  3.1857 -               writeObjectToDisk(getCacheDir(), moduleCacheFile, moduleVersionMap);
  3.1858 -            }
  3.1859 -         }
  3.1860 -      }
  3.1861 -   }
  3.1862 -
  3.1863 -   /**
  3.1864 -    * Update the function cache with newly modified objects
  3.1865 -    */
  3.1866 -   @SuppressWarnings("unchecked")
  3.1867 -   private void updateFunctionCache(DatabaseConnection connection, boolean forceUpdate) {
  3.1868 -      ObjectCacheUpdater cacheUpdater = new ObjectCacheUpdater() {
  3.1869 -
  3.1870 -         @Override
  3.1871 -         public void FetchObjectsFromDatabase(String lastSyncTime, List<String> objects, List<DatabaseObjectInfo> objectInfoList, DatabaseConnection connection) throws SQLException {
  3.1872 -            DatabaseContentUtilities.getFunctions(lastSyncTime, objects, objectInfoList, connection.getJDBCConnection());
  3.1873 -         }
  3.1874 -      };
  3.1875 -      lastFunctionSyncTime = cacheUpdater.updateObjectCache(functionCacheFile, functionNameMap, FUNCTIONS, lastFunctionSyncTime, connection, forceUpdate, null);
  3.1876 -   }
  3.1877 -
  3.1878 -   /**
  3.1879 -    * Update the procedure cache with newly modified objects
  3.1880 -    */
  3.1881 -   @SuppressWarnings("unchecked")
  3.1882 -   private void updateProcedureCache(DatabaseConnection connection, boolean forceUpdate) {
  3.1883 -      ObjectCacheUpdater cacheUpdater = new ObjectCacheUpdater() {
  3.1884 -
  3.1885 -         @Override
  3.1886 -         public void FetchObjectsFromDatabase(String lastSyncTime, List<String> objects, List<DatabaseObjectInfo> objectInfoList, DatabaseConnection connection) throws SQLException {
  3.1887 -            DatabaseContentUtilities.getProcedures(lastSyncTime, objects, objectInfoList, connection.getJDBCConnection());
  3.1888 -         }
  3.1889 -      };
  3.1890 -      lastProcedureSyncTime = cacheUpdater.updateObjectCache(procedureCacheFile, procedureNameMap, PROCEDURES, lastProcedureSyncTime, connection, forceUpdate, null);
  3.1891 -   }
  3.1892 -
  3.1893 -   /**
  3.1894 -    * Update the view cache with newly modified objects
  3.1895 -    */
  3.1896 -   @SuppressWarnings("unchecked")
  3.1897 -   private void updateViewCache(DatabaseConnection connection, boolean forceUpdate) {
  3.1898 -      ObjectCacheUpdater cacheUpdater = new ObjectCacheUpdater() {
  3.1899 -
  3.1900 -         @Override
  3.1901 -         public void FetchObjectsFromDatabase(String lastSyncTime, List<String> objects, List<DatabaseObjectInfo> objectInfoList, DatabaseConnection connection) throws SQLException {
  3.1902 -            DatabaseContentUtilities.getViewNames(lastSyncTime, objects, objectInfoList, connection.getJDBCConnection());
  3.1903 -         }
  3.1904 -      };
  3.1905 -      lastViewSyncTime = cacheUpdater.updateObjectCache(viewCacheFile, viewNameMap, VIEWS, lastViewSyncTime, connection, forceUpdate, new String[]{VIEWS});
  3.1906 -   }
  3.1907 -
  3.1908 -   /**
  3.1909 -    * Get only the columns of the given table
  3.1910 -    * @param String name of view/table
  3.1911 -    * @return Map
  3.1912 -    */
  3.1913 -   public Map<String, String> getColumnObjects(String view, DatabaseConnection databaseConnection) {
  3.1914 -      if (!view.startsWith("\"")) {
  3.1915 -         view = view.toLowerCase(Locale.ENGLISH);
  3.1916 -      }
  3.1917 -      if (isUpdateRunning()) {
  3.1918 -         if (databaseConnection == null || databaseConnection.getJDBCConnection() == null) {
  3.1919 -            return new HashMap<String, String>();
  3.1920 -         }
  3.1921 -         try {
  3.1922 -            return DatabaseContentUtilities.getColumnNames(view, databaseConnection.getSchema(), databaseConnection.getJDBCConnection());
  3.1923 -         } catch (SQLException ex) {
  3.1924 -            fireExceptionThrown(ex);
  3.1925 -            return new HashMap<String, String>();
  3.1926 -         }
  3.1927 -      }
  3.1928 -      synchronized (tableCacheFile) {
  3.1929 -         boolean isTable = isTable(view);
  3.1930 -         Map<String, DatabaseObjectInfo> map = isTable ? tableNameMap : viewNameMap;
  3.1931 -         if (isTable) {
  3.1932 -            if (tableSynonyms.containsKey(view)) {
  3.1933 -               view = tableSynonyms.get(view);
  3.1934 -            }
  3.1935 -         } else {
  3.1936 -            if (viewSynonyms.containsKey(view)) {
  3.1937 -               view = viewSynonyms.get(view);
  3.1938 -            }
  3.1939 -         }
  3.1940 -
  3.1941 -
  3.1942 -         DatabaseObjectInfo objectInfo = map.get(view);
  3.1943 -         if (objectInfo == null) //not a view/table
  3.1944 -         {
  3.1945 -            return new HashMap<String, String>();
  3.1946 -         }
  3.1947 -         Map<String, String> columns = objectInfo.getObjectData();
  3.1948 -         if (columns == null || columns.isEmpty()) { //first look for the cache file
  3.1949 -            columns = readMapFromFile(getCacheDir(), formatCacheFileName(isTable ? TABLES : VIEWS, view));
  3.1950 -            try {
  3.1951 -               if (databaseConnection != null && databaseConnection.getJDBCConnection() != null) {
  3.1952 -                  if (columns == null || columns.isEmpty()) {
  3.1953 -                     String owner = getOwner(view);
  3.1954 -                     columns = DatabaseContentUtilities.getColumnNames(view, owner, databaseConnection.getJDBCConnection());
  3.1955 -                     objectInfo.setObjectData(columns);
  3.1956 -                     writeObjectToDisk(getCacheDir(), formatCacheFileName(isTable ? TABLES : VIEWS, view), columns);
  3.1957 -                  }
  3.1958 -               }
  3.1959 -            } catch (SQLException ex) {
  3.1960 -               //database exception => go offline (this should only happen when the database connection is lost
  3.1961 -               //NB! This code will supress sql syntax errors
  3.1962 -               fireExceptionThrown(ex);
  3.1963 -            }
  3.1964 -            objectInfo.setObjectData(columns);
  3.1965 -         }
  3.1966 -
  3.1967 -         return columns != null ? columns : new HashMap<String, String>();
  3.1968 -      }
  3.1969 -   }
  3.1970 -
  3.1971 -   /**
  3.1972 -    * Update the package cache
  3.1973 -    * @return List of new/modified packages
  3.1974 -    */
  3.1975 -   @SuppressWarnings("unchecked")
  3.1976 -   private void updatePackageCache(DatabaseConnection connection, boolean forceUpdate) {
  3.1977 -      ObjectCacheUpdater cacheUpdater = new ObjectCacheUpdater() {
  3.1978 -
  3.1979 -         @Override
  3.1980 -         public void FetchObjectsFromDatabase(String lastSyncTime, List<String> objects, List<DatabaseObjectInfo> objectInfoList, DatabaseConnection connection) throws SQLException {
  3.1981 -            DatabaseContentUtilities.getPackageNames(lastSyncTime, objects, objectInfoList, connection.getJDBCConnection());
  3.1982 -         }
  3.1983 -      };
  3.1984 -      lastPackageSyncTime = cacheUpdater.updateObjectCache(packageCacheFile, pkgNameMap, PACKAGES, lastPackageSyncTime, connection, forceUpdate, new String[]{PACKAGES, PACKAGE_INFO});
  3.1985 -   }
  3.1986 -
  3.1987 -   private void writeCacheFileToDisk(String timestamp, String mapName, Map objectMap, String cacheFile) {
  3.1988 -      Map<String, Object> cache = new HashMap<String, Object>();
  3.1989 -      cache.put(LAST_FETCH_TIME, timestamp);
  3.1990 -      cache.put(mapName, objectMap);
  3.1991 -      writeObjectToDisk(getCacheDir(), cacheFile, cache);
  3.1992 -   }
  3.1993 -
  3.1994 -   /**
  3.1995 -    * Get only the functions/procedures belonging to the given owner, of the given package
  3.1996 -    * @param pkgName
  3.1997 -    * @return Map of methods
  3.1998 -    */
  3.1999 -   public Map<String, String> getMethodObjects(String pkgName, DatabaseConnection databaseConnection) {
  3.2000 -      if (isUpdateRunning()) {
  3.2001 -         Connection con = databaseConnection.getJDBCConnection();
  3.2002 -         if (databaseConnection == null || databaseConnection.getJDBCConnection() == null) {
  3.2003 -            return new HashMap<String, String>();
  3.2004 -         }
  3.2005 -         try {
  3.2006 -            return DatabaseContentUtilities.getMethodNames(pkgName, databaseConnection.getSchema(), con);
  3.2007 -         } catch (SQLException ex) {
  3.2008 -            fireExceptionThrown(ex);
  3.2009 -            return new HashMap<String, String>();
  3.2010 -         }
  3.2011 -      }
  3.2012 -      synchronized (packageCacheFile) {
  3.2013 -         if (!pkgName.startsWith("\"")) {
  3.2014 -            pkgName = DatabaseContentUtilities.formatPlsqlName(pkgName);
  3.2015 -         }
  3.2016 -         if (packageSynonyms.containsKey(pkgName)) {
  3.2017 -            pkgName = packageSynonyms.get(pkgName);
  3.2018 -         }
  3.2019 -         DatabaseObjectInfo objectInfo = pkgNameMap.get(pkgName);
  3.2020 -         if (objectInfo == null) //not a view/table
  3.2021 -         {
  3.2022 -            return new HashMap<String, String>();
  3.2023 -         }
  3.2024 -         Map<String, String> methods = objectInfo.getObjectData();
  3.2025 -         if (methods == null || methods.isEmpty()) { //first look for the cache file
  3.2026 -            methods = readMapFromFile(getCacheDir(), formatCacheFileName(PACKAGES, pkgName));
  3.2027 -            try {
  3.2028 -               if (databaseConnection != null && databaseConnection.getJDBCConnection() != null) {
  3.2029 -                  if (methods == null || methods.isEmpty()) { //if no cache file - fetch info from database
  3.2030 -                     String owner = getOwner(pkgName);
  3.2031 -                     methods = DatabaseContentUtilities.getMethodNames(pkgName, owner, databaseConnection.getJDBCConnection());
  3.2032 -                     writeObjectToDisk(getCacheDir(), formatCacheFileName(PACKAGES, pkgName), methods);
  3.2033 -                  }
  3.2034 -               }
  3.2035 -            } catch (SQLException ex) {
  3.2036 -               //database exception => go offline (this should only happen when the database connection is lost
  3.2037 -               //NB! This code will supress sql syntax errors
  3.2038 -               fireExceptionThrown(ex);
  3.2039 -            }
  3.2040 -            objectInfo.setObjectData(methods);
  3.2041 -         }
  3.2042 -         return methods != null ? methods : new HashMap<String, String>();
  3.2043 -      }
  3.2044 -   }
  3.2045 -
  3.2046 -   /**
  3.2047 -    * Get exceptions, types and constants in a given package
  3.2048 -    * @param pkgName
  3.2049 -    * @return Map of objects
  3.2050 -    */
  3.2051 -   public Map<String, String> getPackageMembers(String pkgName, DatabaseConnection databaseConnection) {
  3.2052 -      if (isUpdateRunning()) {
  3.2053 -         Connection con = databaseConnection.getJDBCConnection();
  3.2054 -         if (databaseConnection == null || databaseConnection.getJDBCConnection() == null) {
  3.2055 -            return new HashMap<String, String>();
  3.2056 -         }
  3.2057 -         try {
  3.2058 -            return DatabaseContentUtilities.getPackageMembers(pkgName, databaseConnection.getSchema(), con);
  3.2059 -         } catch (SQLException ex) {
  3.2060 -            fireExceptionThrown(ex);
  3.2061 -            return new HashMap<String, String>();
  3.2062 -         }
  3.2063 -      }
  3.2064 -      synchronized (packageCacheFile) {
  3.2065 -         if (!pkgName.startsWith("\"")) {
  3.2066 -            pkgName = DatabaseContentUtilities.formatPlsqlName(pkgName);
  3.2067 -         }
  3.2068 -         if (packageSynonyms.containsKey(pkgName)) {
  3.2069 -            pkgName = packageSynonyms.get(pkgName);
  3.2070 -         }
  3.2071 -         Map<String, String> data = pkgInfoMap.get(pkgName);
  3.2072 -         if (data == null || data.isEmpty()) { //first look for the cache file
  3.2073 -            data = readMapFromFile(getCacheDir(), formatCacheFileName(PACKAGE_INFO, pkgName));
  3.2074 -            try {
  3.2075 -               if (data == null || data.isEmpty()) { //if no cache file - fetch info from database
  3.2076 -                  if (databaseConnection != null && databaseConnection.getJDBCConnection() != null) {
  3.2077 -                     String owner = getOwner(pkgName);
  3.2078 -                     data = DatabaseContentUtilities.getPackageMembers(pkgName, owner, databaseConnection.getJDBCConnection());
  3.2079 -                     writeObjectToDisk(getCacheDir(), formatCacheFileName(PACKAGE_INFO, pkgName), data);
  3.2080 -                  }
  3.2081 -               }
  3.2082 -            } catch (SQLException ex) {
  3.2083 -               //database exception => go offline (this should only happen when the database connection is lost
  3.2084 -               //NB! This code will supress sql syntax errors
  3.2085 -               fireExceptionThrown(ex);
  3.2086 -            }
  3.2087 -            pkgInfoMap.put(pkgName, data);
  3.2088 -         }
  3.2089 -         return data != null ? data : new HashMap<String, String>();
  3.2090 -      }
  3.2091 -   }
  3.2092 -
  3.2093 -   /**
  3.2094 -    * Update cache of database sequences
  3.2095 -    * @return List of newly updated sequences
  3.2096 -    */
  3.2097 -   @SuppressWarnings("unchecked")
  3.2098 -   private void updateSequenceCache(DatabaseConnection connection, boolean forceUpdate) {
  3.2099 -      ObjectCacheUpdater cacheUpdater = new ObjectCacheUpdater() {
  3.2100 -
  3.2101 -         @Override
  3.2102 -         public void FetchObjectsFromDatabase(String lastSyncTime, List<String> objects, List<DatabaseObjectInfo> objectInfoList, DatabaseConnection connection) throws SQLException {
  3.2103 -            DatabaseContentUtilities.getSequences(lastSyncTime, objects, objectInfoList, connection.getJDBCConnection());
  3.2104 -         }
  3.2105 -      };
  3.2106 -      lastSequenceSyncTime = cacheUpdater.updateObjectCache(sequenceCacheFile, seqMap, SEQUENCES, lastSequenceSyncTime, connection, forceUpdate, null);
  3.2107 -   }
  3.2108 -
  3.2109 -   public void refreshItem(String objectName, DatabaseConnection currentConnection) {
  3.2110 -      Map<String, DatabaseObjectInfo> map = null;
  3.2111 -      String[] types = null;
  3.2112 -      String objectNameInCache = objectName.startsWith("\"") ? objectName : objectName.toLowerCase();
  3.2113 -      String camelCaseNameInCache = objectName.startsWith("\"") ? objectName : DatabaseContentUtilities.formatPlsqlName(objectName);
  3.2114 -      if (tableNameMap.containsKey(objectNameInCache)) {
  3.2115 -         map = tableNameMap;
  3.2116 -         types = new String[]{TABLES};
  3.2117 -      } else if (viewNameMap.containsKey(objectNameInCache)) {
  3.2118 -         map = viewNameMap;
  3.2119 -         types = new String[]{VIEWS};
  3.2120 -      } else if (pkgNameMap.containsKey(camelCaseNameInCache)) {
  3.2121 -         objectName = camelCaseNameInCache;
  3.2122 -         map = pkgNameMap;
  3.2123 -         if (pkgInfoMap.containsKey(camelCaseNameInCache)) {
  3.2124 -            pkgInfoMap.remove(camelCaseNameInCache);
  3.2125 -         }
  3.2126 -         types = new String[]{PACKAGES, PACKAGE_INFO};
  3.2127 -      } else if (tableSynonyms.containsKey(objectNameInCache)) {
  3.2128 -         objectName = tableSynonyms.get(objectName);
  3.2129 -         map = tableNameMap;
  3.2130 -         types = new String[]{TABLES};
  3.2131 -      } else if (viewSynonyms.containsKey(objectNameInCache)) {
  3.2132 -         objectName = viewSynonyms.get(objectName);
  3.2133 -         map = viewNameMap;
  3.2134 -         types = new String[]{VIEWS};
  3.2135 -      } else if (functionNameMap.containsKey(camelCaseNameInCache)) {
  3.2136 -         objectName = camelCaseNameInCache;
  3.2137 -         map = functionNameMap;
  3.2138 -         types = new String[]{FUNCTIONS};
  3.2139 -      } else if (procedureNameMap.containsKey(camelCaseNameInCache)) {
  3.2140 -         objectName = camelCaseNameInCache;
  3.2141 -         map = procedureNameMap;
  3.2142 -         types = new String[]{PROCEDURES};
  3.2143 -      }
  3.2144 -      if (map != null) {
  3.2145 -         removeCacheFiles(types, objectName);
  3.2146 -         DatabaseObjectInfo objectInfo = map.get(objectName);
  3.2147 -         objectInfo.setObjectData(null);
  3.2148 -      } else { //check to see if this is a newly created object (and if so add it to the cache)
  3.2149 -         if (objectName == null || objectName.length() == 0) {
  3.2150 -            //full update - run the cache update
  3.2151 -            synchronousCacheUpdate(currentConnection, true);
  3.2152 -         } else {
  3.2153 -            boolean packageFound = false;
  3.2154 -            boolean viewFound = false;
  3.2155 -            boolean tableFound = false;
  3.2156 -            boolean functionFound = false;
  3.2157 -            boolean procedureFound = false;
  3.2158 -            boolean synonymFound = false;
  3.2159 -            Map<String, DatabaseObjectInfo> databaseObjects = DatabaseContentUtilities.getObjectInfo(objectName, currentConnection, lastPackageSyncTime, lastViewSyncTime, lastTableSyncTime, lastSynonymSyncTime);
  3.2160 -            for (String actualName : databaseObjects.keySet()) {
  3.2161 -               DatabaseObjectInfo objectInfo = databaseObjects.get(actualName);
  3.2162 -               if (objectInfo != null && objectInfo.getObjectType() != null) {
  3.2163 -                  String objectType = objectInfo.getObjectType();
  3.2164 -                  if (DatabaseContentUtilities.isValidOracleUppercaseIdentifier(actualName)) {
  3.2165 -                     objectNameInCache = actualName.toLowerCase(Locale.ENGLISH);
  3.2166 -                  } else {
  3.2167 -                     objectNameInCache = "\"" + actualName + "\"";
  3.2168 -                  }
  3.2169 -                  addSchema(objectInfo.getOwner());
  3.2170 -                  if (objectType.startsWith("PACKAGE")) {
  3.2171 -                     objectName = objectNameInCache.startsWith("\"") ? objectNameInCache : DatabaseContentUtilities.formatPlsqlName(actualName);
  3.2172 -                     if (!isPackage(objectName, currentConnection)) {
  3.2173 -                        pkgNameMap.put(objectName, objectInfo);
  3.2174 -                        ownerMap.put(objectNameInCache, objectInfo.getOwner());
  3.2175 -                        packageFound = true;
  3.2176 -                     }
  3.2177 -                  } else if (objectType.equals("VIEW")) {
  3.2178 -                     if (!isView(objectNameInCache)) {
  3.2179 -                        viewNameMap.put(objectNameInCache, objectInfo);
  3.2180 -                        ownerMap.put(objectNameInCache, objectInfo.getOwner());
  3.2181 -                        viewFound = true;
  3.2182 -                     }
  3.2183 -                  } else if (objectType.equals("TABLE")) {
  3.2184 -                     if (!isTable(objectNameInCache)) {
  3.2185 -                        tableFound = true;
  3.2186 -                        tableNameMap.put(objectNameInCache, objectInfo);
  3.2187 -                        ownerMap.put(objectNameInCache, objectInfo.getOwner());
  3.2188 -                     }
  3.2189 -                  } else if (objectType.equals("FUNCTION")) {
  3.2190 -                     objectName = objectNameInCache.startsWith("\"") ? objectNameInCache : DatabaseContentUtilities.formatPlsqlName(actualName);
  3.2191 -                     if (!isFunction(objectName)) {
  3.2192 -                        functionFound = true;
  3.2193 -                        functionNameMap.put(objectName, objectInfo);
  3.2194 -                        ownerMap.put(objectNameInCache, objectInfo.getOwner());
  3.2195 -                     }
  3.2196 -                  } else if (objectType.equals("PROCEDURE")) {
  3.2197 -                     objectName = objectNameInCache.startsWith("\"") ? objectNameInCache : DatabaseContentUtilities.formatPlsqlName(actualName);
  3.2198 -                     if (!isProcedure(objectName)) {
  3.2199 -                        procedureFound = true;
  3.2200 -                        procedureNameMap.put(objectName, objectInfo);
  3.2201 -                        ownerMap.put(objectNameInCache, objectInfo.getOwner());
  3.2202 -                     }
  3.2203 -                  } else if (objectType.equals("SYNONYM")) {
  3.2204 -                     synonymFound = true;
  3.2205 -                     //for now just refresh all synonyms if this happens
  3.2206 -                  }
  3.2207 -               }
  3.2208 -            }
  3.2209 -            if (packageFound) {
  3.2210 -               writeCacheFileToDisk(lastPackageSyncTime, PACKAGES, pkgNameMap, packageCacheFile);
  3.2211 -            }
  3.2212 -            if (tableFound) {
  3.2213 -               writeCacheFileToDisk(lastTableSyncTime, TABLES, tableNameMap, tableCacheFile);
  3.2214 -            }
  3.2215 -            if (viewFound) {
  3.2216 -               writeCacheFileToDisk(lastViewSyncTime, VIEWS, viewNameMap, viewCacheFile);
  3.2217 -            }
  3.2218 -            if (functionFound) {
  3.2219 -               writeCacheFileToDisk(lastFunctionSyncTime, FUNCTIONS, functionNameMap, functionCacheFile);
  3.2220 -            }
  3.2221 -            if (procedureFound) {
  3.2222 -               writeCacheFileToDisk(lastProcedureSyncTime, PROCEDURES, procedureNameMap, procedureCacheFile);
  3.2223 -            }
  3.2224 -            if (packageFound || tableFound || viewFound || procedureFound || functionFound) {
  3.2225 -               writeObjectToDisk(getCacheDir(), ownerCacheFile, ownerMap);
  3.2226 -            }
  3.2227 -            if (synonymFound) {
  3.2228 -               updateSynonymCache(currentConnection, true);
  3.2229 -            }
  3.2230 -         }
  3.2231 -      }
  3.2232 -   }
  3.2233 -
  3.2234 -   public boolean isTable(String objectName) {
  3.2235 -      if (objectName == null) {
  3.2236 -         return false;
  3.2237 -      }
  3.2238 -      if (!objectName.startsWith("\"")) {
  3.2239 -         objectName = objectName.toLowerCase(Locale.ENGLISH);
  3.2240 -      }
  3.2241 -      return tableNameMap.containsKey(objectName) || tableSynonyms.containsKey(objectName);
  3.2242 -   }
  3.2243 -
  3.2244 -   public boolean isView(String objectName) {
  3.2245 -      if (objectName == null) {
  3.2246 -         return false;
  3.2247 -      }
  3.2248 -      if (!objectName.startsWith("\"")) {
  3.2249 -         objectName = objectName.toLowerCase(Locale.ENGLISH);
  3.2250 -      }
  3.2251 -      return viewNameMap.containsKey(objectName) || viewSynonyms.containsKey(objectName);
  3.2252 -   }
  3.2253 -
  3.2254 -   public boolean isViewSynonym(String objectName) {
  3.2255 -      if (objectName == null) {
  3.2256 -         return false;
  3.2257 -      }
  3.2258 -      return viewSynonyms.containsKey(objectName.toLowerCase(Locale.ENGLISH));
  3.2259 -   }
  3.2260 -
  3.2261 -   public String getViewForSynonym(String objectName) {
  3.2262 -      if (objectName == null) {
  3.2263 -         return null;
  3.2264 -      }
  3.2265 -      if (!objectName.startsWith("\"")) {
  3.2266 -         objectName = objectName.toLowerCase(Locale.ENGLISH);
  3.2267 -      }
  3.2268 -      return viewSynonyms.get(objectName);
  3.2269 -   }
  3.2270 -
  3.2271 -   public boolean isTableSynonym(String objectName) {
  3.2272 -      if (objectName == null) {
  3.2273 -         return false;
  3.2274 -      }
  3.2275 -      if (!objectName.startsWith("\"")) {
  3.2276 -         objectName = objectName.toLowerCase(Locale.ENGLISH);
  3.2277 -      }
  3.2278 -      return tableSynonyms.containsKey(objectName);
  3.2279 -   }
  3.2280 -
  3.2281 -   public String getTableForSynonym(String objectName) {
  3.2282 -      if (objectName == null) {
  3.2283 -         return null;
  3.2284 -      }
  3.2285 -      if (!objectName.startsWith("\"")) {
  3.2286 -         objectName = objectName.toLowerCase(Locale.ENGLISH);
  3.2287 -      }
  3.2288 -      return tableSynonyms.get(objectName);
  3.2289 -   }
  3.2290 -
  3.2291 -   public boolean isPackageSynonym(String objectName) {
  3.2292 -      if (objectName == null) {
  3.2293 -         return false;
  3.2294 -      }
  3.2295 -      if (!objectName.startsWith("\"")) {
  3.2296 -         objectName = DatabaseContentUtilities.formatPlsqlName(objectName);
  3.2297 -      }
  3.2298 -      return packageSynonyms.containsKey(objectName);
  3.2299 -   }
  3.2300 -
  3.2301 -   public String getPackageForSynonym(String objectName) {
  3.2302 -      if (objectName == null) {
  3.2303 -         return null;
  3.2304 -      }
  3.2305 -      if (!objectName.startsWith("\"")) {
  3.2306 -         objectName = DatabaseContentUtilities.formatPlsqlName(objectName);
  3.2307 -      }
  3.2308 -      return packageSynonyms.get(objectName);
  3.2309 -   }
  3.2310 -
  3.2311 -   public boolean isPackage(String objectName, DatabaseConnection currentConnection) {
  3.2312 -      if (objectName == null) {
  3.2313 -         return false;
  3.2314 -      }
  3.2315 -      if (!objectName.startsWith("\"")) {
  3.2316 -         objectName = DatabaseContentUtilities.formatPlsqlName(objectName);
  3.2317 -      }
  3.2318 -      return pkgNameMap.containsKey(objectName) || packageSynonyms.containsKey(objectName);
  3.2319 -   }
  3.2320 -
  3.2321 -   public boolean isLogicalUnit(String objectName) {
  3.2322 -      if (objectName == null) {
  3.2323 -         return false;
  3.2324 -      }
  3.2325 -      return logicalUnitSet != null && logicalUnitSet.contains(objectName);
  3.2326 -   }
  3.2327 -
  3.2328 -   public boolean isEnumerationType(String objectName) {
  3.2329 -      if (objectName == null) {
  3.2330 -         return false;
  3.2331 -      }
  3.2332 -      return enumerationSet != null && enumerationSet.contains(objectName);
  3.2333 -   }
  3.2334 -
  3.2335 -   public boolean isSequence(String objectName) {
  3.2336 -      if (objectName == null) {
  3.2337 -         return false;
  3.2338 -      }
  3.2339 -      if (!objectName.startsWith("\"")) {
  3.2340 -         objectName = objectName.toLowerCase(Locale.ENGLISH);
  3.2341 -      }
  3.2342 -      return this.seqMap.containsKey(objectName);
  3.2343 -   }
  3.2344 -
  3.2345 -   public boolean isFunction(String objectName) {
  3.2346 -      if (objectName == null) {
  3.2347 -         return false;
  3.2348 -      }
  3.2349 -      if (!objectName.startsWith("\"")) {
  3.2350 -         objectName = DatabaseContentUtilities.formatPlsqlName(objectName);
  3.2351 -      }
  3.2352 -      return this.functionNameMap.containsKey(objectName);
  3.2353 -   }
  3.2354 -
  3.2355 -   public boolean isProcedure(String objectName) {
  3.2356 -      if (objectName == null) {
  3.2357 -         return false;
  3.2358 -      }
  3.2359 -      if (!objectName.startsWith("\"")) {
  3.2360 -         objectName = DatabaseContentUtilities.formatPlsqlName(objectName);
  3.2361 -      }
  3.2362 -      return this.procedureNameMap.containsKey(objectName);
  3.2363 -   }
  3.2364 -
  3.2365 -   public boolean isSchema(String objectName) {
  3.2366 -      if (objectName == null) {
  3.2367 -         return false;
  3.2368 -      }
  3.2369 -      //IFS specific workaround for appowner prefix as used in client code
  3.2370 -      if ("&AO".equals(objectName)) {
  3.2371 -         objectName = "IFSAPP";
  3.2372 -      }
  3.2373 -      if (!objectName.startsWith("\"")) {
  3.2374 -         objectName = objectName.toUpperCase(Locale.ENGLISH);
  3.2375 -      }
  3.2376 -      return schemaSet.contains(objectName);
  3.2377 -   }
  3.2378 -
  3.2379 -   public Set<String> listLogicalUnits() {
  3.2380 -      return logicalUnitSet;
  3.2381 -   }
  3.2382 -
  3.2383 -   public Set<String> listEnumerationTypes() {
  3.2384 -      return enumerationSet;
  3.2385 -   }
  3.2386 -
  3.2387 -   public DatabaseObjectInfo getViewInfo(String viewName, DatabaseConnection databaseConnection) {
  3.2388 -      if (!updateThread.isFinished()) {
  3.2389 -         return DatabaseContentUtilities.getViewInfo(viewName, databaseConnection);
  3.2390 -      }
  3.2391 -      return viewNameMap.get(viewName.toLowerCase(Locale.ENGLISH));
  3.2392 -   }
  3.2393 -
  3.2394 -   public DatabaseObjectInfo getPackageInfo(String pkgName, DatabaseConnection databaseConnection) {
  3.2395 -      DatabaseObjectInfo info = pkgNameMap.get(DatabaseContentUtilities.formatPlsqlName(pkgName));
  3.2396 -      if ((info == null || info.getLuName() == null) && databaseConnection != null) { //data not cached - fetched from the database
  3.2397 -         if (info == null) {
  3.2398 -            info = new DatabaseObjectInfo(databaseConnection.getSchema());
  3.2399 -         }
  3.2400 -         DatabaseContentUtilities.getMetaDataForPackage(databaseConnection.getJDBCConnection(), pkgName, info);
  3.2401 -      }
  3.2402 -      return info;
  3.2403 -   }
  3.2404 -
  3.2405 -   public String getModuleVersion(String moduleName) {
  3.2406 -      return moduleVersionMap.get(moduleName.toLowerCase(Locale.ENGLISH));
  3.2407 -   }
  3.2408 -
  3.2409 -   public String getOwner(String objectName) {
  3.2410 -      String owner = ownerMap.get(objectName.toLowerCase(Locale.ENGLISH));
  3.2411 -      return (owner == null ? "" : owner);
  3.2412 -   }
  3.2413 -
  3.2414 -   public String getLastPackageSyncTime() {
  3.2415 -      return lastPackageSyncTime;
  3.2416 -   }
  3.2417 -
  3.2418 -   public String getLastTableSyncTime() {
  3.2419 -      return lastTableSyncTime;
  3.2420 -   }
  3.2421 -
  3.2422 -   public String getLastViewSyncTime() {
  3.2423 -      return lastViewSyncTime;
  3.2424 -   }
  3.2425 -
  3.2426 -   public boolean isUpdateRunning() {
  3.2427 -      return (updateThread != null && !updateThread.isFinished());
  3.2428 -   }
  3.2429 -
  3.2430 -   public void addExceptionListener(ExceptionListener listener) {
  3.2431 -      listeners.add(listener);
  3.2432 -   }
  3.2433 -
  3.2434 -   public void removeExceptionListener(ExceptionListener listener) {
  3.2435 -      listeners.remove(listener);
  3.2436 -   }
  3.2437 -
  3.2438 -   private void fireExceptionThrown(Exception e) {
  3.2439 -      for (ExceptionListener listener : listeners) {
  3.2440 -         listener.exceptionThrown(e);
  3.2441 -      }
  3.2442 -   }
  3.2443 -
  3.2444 -   public String getFndbasVersion() {
  3.2445 -      return getModuleVersion("fndbas");
  3.2446 -   }
  3.2447 -
  3.2448 -   private abstract class ObjectCacheUpdater {
  3.2449 -
  3.2450 -      public String updateObjectCache(String fileName, Map objectMap, String cacheEntryName, String lastSyncTime, DatabaseConnection connection, boolean forceUpdate, String[] detailFileTypes) {
  3.2451 -         synchronized (fileName) {
  3.2452 -            if (objectMap.isEmpty()) {
  3.2453 -               Map cache = readMapFromFile(getCacheDir(), fileName);
  3.2454 -               if (cache != null) {
  3.2455 -                  lastSyncTime = (String) cache.get(LAST_FETCH_TIME);
  3.2456 -                  Map tempMap = (Map) cache.get(cacheEntryName);
  3.2457 -                  if (tempMap != null) {
  3.2458 -                     objectMap.putAll(tempMap);
  3.2459 -                  }
  3.2460 -               } else {
  3.2461 -                  lastSyncTime = BEGINNING_OF_TIME;
  3.2462 -               }
  3.2463 -            }
  3.2464 -            if (lastSyncTime == null) {
  3.2465 -               lastSyncTime = BEGINNING_OF_TIME; //update list with latest updates from database
  3.2466 -            }
  3.2467 -            if (connection != null && connection.getJDBCConnection() != null && (forceUpdate || BEGINNING_OF_TIME.equals(lastSyncTime))) {
  3.2468 -               try {
  3.2469 -                  List<String> objects = new ArrayList<String>();
  3.2470 -                  List<DatabaseObjectInfo> objectInfoList = new ArrayList<DatabaseObjectInfo>();
  3.2471 -                  FetchObjectsFromDatabase(lastSyncTime, objects, objectInfoList, connection);
  3.2472 -                  for (int i = 0; i < objects.size(); i++) {
  3.2473 -                     String name = objects.get(i);
  3.2474 -                     if (detailFileTypes != null) {
  3.2475 -                        removeCacheFiles(detailFileTypes, name);
  3.2476 -                     }
  3.2477 -                     DatabaseObjectInfo info = objectInfoList.isEmpty() ? null : objectInfoList.get(i);
  3.2478 -                     if (info != null) {
  3.2479 -                        ownerMap.put(name.toLowerCase(Locale.ENGLISH), info.getOwner());
  3.2480 -                     }
  3.2481 -                     objectMap.put(name, info);
  3.2482 -                  }
  3.2483 -                  if (objects.size() > 0) {
  3.2484 -                     String timestamp = DatabaseContentUtilities.getCurrentTime(connection.getJDBCConnection());
  3.2485 -                     writeCacheFileToDisk(timestamp, cacheEntryName, objectMap, fileName);
  3.2486 -                     if (!objectInfoList.isEmpty()) {
  3.2487 -                        writeObjectToDisk(getCacheDir(), ownerCacheFile, ownerMap);
  3.2488 -                     }
  3.2489 -                     lastSyncTime = timestamp;
  3.2490 -                  }
  3.2491 -               } catch (SQLException ex) {
  3.2492 -                  //database exception => go offline (this should only happen when the database connection is lost
  3.2493 -                  //NB! This code will supress sql syntax errors
  3.2494 -                  fireExceptionThrown(ex);
  3.2495 -               }
  3.2496 -            }
  3.2497 -         }
  3.2498 -         return lastSyncTime;
  3.2499 -      }
  3.2500 -
  3.2501 -      public abstract void FetchObjectsFromDatabase(String lastSyncTime, List<String> objects, List<DatabaseObjectInfo> objectInfoList, DatabaseConnection connection) throws SQLException;
  3.2502 -   }
  3.2503 +        public abstract void FetchObjectsFromDatabase(String lastSyncTime, List<String> objects, List<DatabaseObjectInfo> objectInfoList, DatabaseConnection connection) throws SQLException;
  3.2504 +    }
  3.2505  }