svn commit: r1291007 - in /ofbiz/trunk/framework: datafile/src/org/ofbiz/datafile/ModelDataFileReader.java webtools/webapp/webtools/WEB-INF/actions/datafile/viewdatafile.groovy

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r1291007 - in /ofbiz/trunk/framework: datafile/src/org/ofbiz/datafile/ModelDataFileReader.java webtools/webapp/webtools/WEB-INF/actions/datafile/viewdatafile.groovy

adrianc
Author: adrianc
Date: Sun Feb 19 14:39:10 2012
New Revision: 1291007

URL: http://svn.apache.org/viewvc?rev=1291007&view=rev
Log:
Refactored ModelDataFileReader.java - fixed thread-safety issues, simplified some unnecessarily complicated code, un-hide exceptions so the UI can display them.

Modified:
    ofbiz/trunk/framework/datafile/src/org/ofbiz/datafile/ModelDataFileReader.java
    ofbiz/trunk/framework/webtools/webapp/webtools/WEB-INF/actions/datafile/viewdatafile.groovy

Modified: ofbiz/trunk/framework/datafile/src/org/ofbiz/datafile/ModelDataFileReader.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/datafile/src/org/ofbiz/datafile/ModelDataFileReader.java?rev=1291007&r1=1291006&r2=1291007&view=diff
==============================================================================
--- ofbiz/trunk/framework/datafile/src/org/ofbiz/datafile/ModelDataFileReader.java (original)
+++ ofbiz/trunk/framework/datafile/src/org/ofbiz/datafile/ModelDataFileReader.java Sun Feb 19 14:39:10 2012
@@ -18,174 +18,53 @@
  *******************************************************************************/
 package org.ofbiz.datafile;
 
-
-import java.io.IOException;
 import java.net.URL;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 
-import javax.xml.parsers.ParserConfigurationException;
-
 import org.ofbiz.base.util.Debug;
-import org.ofbiz.base.util.UtilTimer;
 import org.ofbiz.base.util.UtilValidate;
 import org.ofbiz.base.util.UtilXml;
 import org.ofbiz.base.util.cache.UtilCache;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
-import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
-
 
 /**
  * Flat File definition reader
  */
 
-public class ModelDataFileReader {
+public final class ModelDataFileReader {
 
     public static final String module = ModelDataFileReader.class.getName();
+    private static UtilCache<URL, ModelDataFileReader> readers = UtilCache.createUtilCache("ModelDataFile", true);
 
-    public static UtilCache<URL, ModelDataFileReader> readers = UtilCache.createUtilCache("ModelDataFile", 0, 0);
-
-    public URL readerURL = null;
-    public Map<String, ModelDataFile> modelDataFiles = null;
-
-    public static ModelDataFileReader getModelDataFileReader(URL readerURL) {
-        ModelDataFileReader reader = null;
-
-        reader = readers.get(readerURL);
-        if (reader == null) { // don't want to block here
-            synchronized (ModelDataFileReader.class) {
-                // must check if null again as one of the blocked threads can still enter
-                reader = readers.get(readerURL);
-                if (reader == null) {
-                    if (Debug.infoOn()) Debug.logInfo("[ModelDataFileReader.getModelDataFileReader] : creating reader.", module);
-                    reader = new ModelDataFileReader(readerURL);
-                    readers.put(readerURL, reader);
-                }
-            }
-        }
-        if (reader != null && UtilValidate.isEmpty(reader.modelDataFiles)) {
-            readers.remove(readerURL);
-            return null;
+    public static ModelDataFileReader getModelDataFileReader(URL readerURL) throws DataFileException {
+        ModelDataFileReader reader = readers.get(readerURL);
+        if (reader == null) {
+            if (Debug.infoOn())
+                Debug.logInfo("[ModelDataFileReader.getModelDataFileReader] : creating reader for " + readerURL, module);
+            reader = new ModelDataFileReader(readerURL);
+            readers.putIfAbsent(readerURL, reader);
         }
-        if (Debug.infoOn()) Debug.logInfo("[ModelDataFileReader.getModelDataFileReader] : returning reader.", module);
+        if (Debug.infoOn())
+            Debug.logInfo("[ModelDataFileReader.getModelDataFileReader] : returning reader for " + readerURL, module);
         return reader;
     }
 
-    public ModelDataFileReader(URL readerURL) {
-        this.readerURL = readerURL;
-
-        // preload models...
-        getModelDataFiles();
-    }
-
-    public Map<String, ModelDataFile> getModelDataFiles() {
-        if (modelDataFiles == null) { // don't want to block here
-            synchronized (ModelDataFileReader.class) {
-                // must check if null again as one of the blocked threads can still enter
-                if (modelDataFiles == null) { // now it's safe
-                    modelDataFiles = new HashMap<String, ModelDataFile>();
-
-                    UtilTimer utilTimer = new UtilTimer();
-
-                    utilTimer.timerString("Before getDocument in file " + readerURL);
-                    Document document = getDocument(readerURL);
-
-                    if (document == null) {
-                        modelDataFiles = null;
-                        return null;
-                    }
-
-                    utilTimer.timerString("Before getDocumentElement in file " + readerURL);
-                    Element docElement = document.getDocumentElement();
-
-                    if (docElement == null) {
-                        modelDataFiles = null;
-                        return null;
-                    }
-                    docElement.normalize();
-                    Node curChild = docElement.getFirstChild();
-
-                    int i = 0;
-
-                    if (curChild != null) {
-                        utilTimer.timerString("Before start of dataFile loop in file " + readerURL);
-                        do {
-                            if (curChild.getNodeType() == Node.ELEMENT_NODE && "data-file".equals(curChild.getNodeName())) {
-                                i++;
-                                Element curDataFile = (Element) curChild;
-                                String dataFileName = UtilXml.checkEmpty(curDataFile.getAttribute("name"));
-
-                                // check to see if dataFile with same name has already been read
-                                if (modelDataFiles.containsKey(dataFileName)) {
-                                    Debug.logWarning("WARNING: DataFile " + dataFileName +
-                                        " is defined more than once, most recent will over-write previous definition(s)", module);
-                                }
-
-                                // utilTimer.timerString("  After dataFileName -- " + i + " --");
-                                ModelDataFile dataFile = createModelDataFile(curDataFile);
-
-                                // utilTimer.timerString("  After createModelDataFile -- " + i + " --");
-                                if (dataFile != null) {
-                                    modelDataFiles.put(dataFileName, dataFile);
-                                    // utilTimer.timerString("  After modelDataFiles.put -- " + i + " --");
-                                    if (Debug.infoOn()) Debug.logInfo("-- getModelDataFile: #" + i + " Loaded dataFile: " + dataFileName, module);
-                                } else
-                                    Debug.logWarning("-- -- SERVICE ERROR:getModelDataFile: Could not create dataFile for dataFileName: " + dataFileName, module);
-
-                            }
-                        } while ((curChild = curChild.getNextSibling()) != null);
-                    } else {
-                        Debug.logWarning("No child nodes found.", module);
-                    }
-                    utilTimer.timerString("Finished file " + readerURL + " - Total Flat File Defs: " + i + " FINISHED");
-                }
-            }
-        }
-        return modelDataFiles;
-    }
-
-    /** Gets an DataFile object based on a definition from the specified XML DataFile descriptor file.
-     * @param dataFileName The dataFileName of the DataFile definition to use.
-     * @return An DataFile object describing the specified dataFile of the specified descriptor file.
-     */
-    public ModelDataFile getModelDataFile(String dataFileName) {
-        Map<String, ModelDataFile> ec = getModelDataFiles();
-
-        if (ec != null) {
-            return ec.get(dataFileName);
-        } else {
-            return null;
-        }
-    }
-
-    /** Creates a Iterator with the dataFileName of each DataFile defined in the specified XML DataFile Descriptor file.
-     * @return A Iterator of dataFileName Strings
-     */
-    public Iterator<String> getDataFileNamesIterator() {
-        Collection<String> collection = getDataFileNames();
-
-        if (collection != null) {
-            return collection.iterator();
-        } else {
-            return null;
-        }
-    }
-
-    /** Creates a Collection with the dataFileName of each DataFile defined in the specified XML DataFile Descriptor file.
-     * @return A Collection of dataFileName Strings
-     */
-    public Collection<String> getDataFileNames() {
-        Map<String, ModelDataFile> ec = getModelDataFiles();
+    private final URL readerURL;
+    private final Map<String, ModelDataFile> modelDataFiles;
 
-        return ec.keySet();
+    public ModelDataFileReader(URL readerURL) throws DataFileException {
+        this.readerURL = readerURL;
+        this.modelDataFiles = Collections.unmodifiableMap(createModelDataFiles());
     }
 
-    protected ModelDataFile createModelDataFile(Element dataFileElement) {
+    private ModelDataFile createModelDataFile(Element dataFileElement) {
         ModelDataFile dataFile = new ModelDataFile();
         String tempStr;
 
@@ -224,7 +103,7 @@ public class ModelDataFileReader {
             }
         }
 
-        for (ModelRecord modelRecord: dataFile.records) {
+        for (ModelRecord modelRecord : dataFile.records) {
 
             if (modelRecord.parentName.length() > 0) {
                 ModelRecord parentRecord = dataFile.getModelRecord(modelRecord.parentName);
@@ -241,7 +120,89 @@ public class ModelDataFileReader {
         return dataFile;
     }
 
-    protected ModelRecord createModelRecord(Element recordElement) {
+    private Map<String, ModelDataFile> createModelDataFiles() throws DataFileException {
+        Document document = null;
+        Element docElement = null;
+        try {
+            document = UtilXml.readXmlDocument(this.readerURL);
+        } catch (Exception e) {
+            Debug.logWarning(e, "Error while reading " + this.readerURL + ": ", module);
+            throw new DataFileException("Error while reading " + this.readerURL, e);
+        }
+        if (document != null) {
+            docElement = document.getDocumentElement();
+        }
+        if (docElement == null) {
+            Debug.logWarning("Document element not found in " + this.readerURL, module);
+            throw new DataFileException("Document element not found in " + this.readerURL);
+        }
+        docElement.normalize();
+        List<? extends Element> dataFileElements = UtilXml.childElementList(docElement, "data-file");
+        if (dataFileElements.size() == 0) {
+            Debug.logWarning("No <data-file> elements found in " + this.readerURL, module);
+            throw new DataFileException("No <data-file> elements found in " + this.readerURL);
+        }
+        Map<String, ModelDataFile> result = new HashMap<String, ModelDataFile>();
+        for (Element curDataFile : dataFileElements) {
+            String dataFileName = UtilXml.checkEmpty(curDataFile.getAttribute("name"));
+            if (result.containsKey(dataFileName)) {
+                Debug.logWarning("DataFile " + dataFileName + " is defined more than once, most recent will over-write previous definition(s)", module);
+            }
+            ModelDataFile dataFile = createModelDataFile(curDataFile);
+            if (dataFile != null) {
+                result.put(dataFileName, dataFile);
+                if (Debug.verboseOn()) {
+                    Debug.logVerbose("Loaded dataFile: " + dataFileName, module);
+                }
+            } else {
+                Debug.logWarning("Could not create dataFile for dataFileName " + dataFileName, module);
+                throw new DataFileException("Could not create dataFile for " + dataFileName + " defined in " + this.readerURL);
+            }
+        }
+        return result;
+    }
+
+    private ModelField createModelField(Element fieldElement) {
+        ModelField field = new ModelField();
+        String tempStr;
+
+        field.name = UtilXml.checkEmpty(fieldElement.getAttribute("name"));
+
+        tempStr = UtilXml.checkEmpty(fieldElement.getAttribute("position"));
+        if (UtilValidate.isNotEmpty(tempStr)) {
+            field.position = Integer.parseInt(tempStr);
+        }
+        tempStr = UtilXml.checkEmpty(fieldElement.getAttribute("length"));
+        if (UtilValidate.isNotEmpty(tempStr)) {
+            field.length = Integer.parseInt(tempStr);
+        }
+
+        field.type = UtilXml.checkEmpty(fieldElement.getAttribute("type"));
+        field.format = UtilXml.checkEmpty(fieldElement.getAttribute("format"));
+        field.validExp = UtilXml.checkEmpty(fieldElement.getAttribute("valid-exp"));
+        field.description = UtilXml.checkEmpty(fieldElement.getAttribute("description"));
+        field.defaultValue = UtilXml.checkEmpty(fieldElement.getAttribute("default-value"));
+        field.refField = UtilXml.checkEmpty(fieldElement.getAttribute("ref-field"));
+
+        tempStr = UtilXml.checkEmpty(fieldElement.getAttribute("prim-key"));
+        if (UtilValidate.isNotEmpty(tempStr)) {
+            field.isPk = Boolean.parseBoolean(tempStr);
+        }
+
+        tempStr = UtilXml.checkEmpty(fieldElement.getAttribute("ignored"));
+        if (UtilValidate.isNotEmpty(tempStr)) {
+            field.ignored = Boolean.parseBoolean(tempStr);
+        }
+
+        tempStr = UtilXml.checkEmpty(fieldElement.getAttribute("expression"));
+        if (UtilValidate.isNotEmpty(tempStr)) {
+            field.expression = Boolean.parseBoolean(tempStr);
+        }
+
+        return field;
+    }
+
+    private ModelRecord createModelRecord(Element recordElement) {
         ModelRecord record = new ModelRecord();
         String tempStr;
 
@@ -249,9 +210,11 @@ public class ModelDataFileReader {
         record.typeCode = UtilXml.checkEmpty(recordElement.getAttribute("type-code"));
 
         record.tcMin = UtilXml.checkEmpty(recordElement.getAttribute("tc-min"));
-        if (record.tcMin.length() > 0) record.tcMinNum = Long.parseLong(record.tcMin);
+        if (record.tcMin.length() > 0)
+            record.tcMinNum = Long.parseLong(record.tcMin);
         record.tcMax = UtilXml.checkEmpty(recordElement.getAttribute("tc-max"));
-        if (record.tcMax.length() > 0) record.tcMaxNum = Long.parseLong(record.tcMax);
+        if (record.tcMax.length() > 0)
+            record.tcMaxNum = Long.parseLong(record.tcMax);
 
         tempStr = UtilXml.checkEmpty(recordElement.getAttribute("tc-isnum"));
         if (UtilValidate.isNotEmpty(tempStr)) {
@@ -278,7 +241,8 @@ public class ModelDataFileReader {
             Element fieldElement = (Element) fList.item(i);
             ModelField modelField = createModelField(fieldElement);
 
-            // if the position is not specified, assume the start position based on last entry
+            // if the position is not specified, assume the start position based on last
+            // entry
             if ((i > 0) && (modelField.position == -1)) {
                 modelField.position = priorEnd;
             }
@@ -294,69 +258,40 @@ public class ModelDataFileReader {
         return record;
     }
 
-    protected ModelField createModelField(Element fieldElement) {
-        ModelField field = new ModelField();
-        String tempStr;
-
-        field.name = UtilXml.checkEmpty(fieldElement.getAttribute("name"));
-
-        tempStr = UtilXml.checkEmpty(fieldElement.getAttribute("position"));
-        if (UtilValidate.isNotEmpty(tempStr)) {
-            field.position = Integer.parseInt(tempStr);
-        }
-        tempStr = UtilXml.checkEmpty(fieldElement.getAttribute("length"));
-        if (UtilValidate.isNotEmpty(tempStr)) {
-            field.length = Integer.parseInt(tempStr);
-        }
-
-        field.type = UtilXml.checkEmpty(fieldElement.getAttribute("type"));
-        field.format = UtilXml.checkEmpty(fieldElement.getAttribute("format"));
-        field.validExp = UtilXml.checkEmpty(fieldElement.getAttribute("valid-exp"));
-        field.description = UtilXml.checkEmpty(fieldElement.getAttribute("description"));
-        field.defaultValue = UtilXml.checkEmpty(fieldElement.getAttribute("default-value"));
-        field.refField = UtilXml.checkEmpty(fieldElement.getAttribute("ref-field"));
-
-        tempStr = UtilXml.checkEmpty(fieldElement.getAttribute("prim-key"));
-        if (UtilValidate.isNotEmpty(tempStr)) {
-            field.isPk = Boolean.parseBoolean(tempStr);
-        }
-
-        tempStr = UtilXml.checkEmpty(fieldElement.getAttribute("ignored"));
-        if (UtilValidate.isNotEmpty(tempStr)) {
-            field.ignored = Boolean.parseBoolean(tempStr);
-        }
-
-        tempStr = UtilXml.checkEmpty(fieldElement.getAttribute("expression"));
-        if (UtilValidate.isNotEmpty(tempStr)) {
-            field.expression = Boolean.parseBoolean(tempStr);
-        }
-
-        return field;
+    /**
+     * Creates a Collection with the dataFileName of each DataFile defined in the
+     * specified XML DataFile Descriptor file.
+     *
+     * @return A Collection of dataFileName Strings
+     */
+    public Collection<String> getDataFileNames() {
+        return this.modelDataFiles.keySet();
     }
 
-    protected Document getDocument(URL url) {
-        if (url == null)
-            return null;
-        Document document = null;
-
-        try {
-            document = UtilXml.readXmlDocument(url);
-        } catch (SAXException sxe) {
-            // Error generated during parsing)
-            Exception x = sxe;
+    /**
+     * Creates a Iterator with the dataFileName of each DataFile defined in the specified
+     * XML DataFile Descriptor file.
+     *
+     * @return A Iterator of dataFileName Strings
+     */
+    public Iterator<String> getDataFileNamesIterator() {
+        return this.modelDataFiles.keySet().iterator();
+    }
 
-            if (sxe.getException() != null) {
-                x = sxe.getException();
-            }
-            x.printStackTrace();
-        } catch (ParserConfigurationException pce) {
-            // Parser with specified options can't be built
-            pce.printStackTrace();
-        } catch (IOException ioe) {
-            ioe.printStackTrace();
-        }
+    /**
+     * Gets an DataFile object based on a definition from the specified XML DataFile
+     * descriptor file.
+     *
+     * @param dataFileName
+     *            The dataFileName of the DataFile definition to use.
+     * @return An DataFile object describing the specified dataFile of the specified
+     *         descriptor file.
+     */
+    public ModelDataFile getModelDataFile(String dataFileName) {
+        return this.modelDataFiles.get(dataFileName);
+    }
 
-        return document;
+    public Map<String, ModelDataFile> getModelDataFiles() {
+        return this.modelDataFiles;
     }
 }
-

Modified: ofbiz/trunk/framework/webtools/webapp/webtools/WEB-INF/actions/datafile/viewdatafile.groovy
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/webtools/webapp/webtools/WEB-INF/actions/datafile/viewdatafile.groovy?rev=1291007&r1=1291006&r2=1291007&view=diff
==============================================================================
--- ofbiz/trunk/framework/webtools/webapp/webtools/WEB-INF/actions/datafile/viewdatafile.groovy (original)
+++ ofbiz/trunk/framework/webtools/webapp/webtools/WEB-INF/actions/datafile/viewdatafile.groovy Sun Feb 19 14:39:10 2012
@@ -52,10 +52,15 @@ catch (java.net.MalformedURLException e)
 
 definitionNames = null;
 if (definitionUrl) {
-    ModelDataFileReader reader = ModelDataFileReader.getModelDataFileReader(definitionUrl);
-    if (reader) {
-        definitionNames = ((Collection)reader.getDataFileNames()).iterator();
-        context.put("definitionNames", definitionNames);
+    try {
+        ModelDataFileReader reader = ModelDataFileReader.getModelDataFileReader(definitionUrl);
+        if (reader) {
+            definitionNames = ((Collection)reader.getDataFileNames()).iterator();
+            context.put("definitionNames", definitionNames);
+        }
+    }
+    catch (Exception e) {
+        messages.add(e.getMessage());
     }
 }