> Hello,
> 
> I have developed a Java web application based on Tomcat which reads shape 
> files and imports the geometries into a PostGis database. When only a single 
> user imports his data, then so far everything works very well. But if two or 
> more concurrent users want to import their shape files, then the application 
> crashes. 
> 
> The workflow is the following: 
> A user loads a zip file up to the server. For each zip file, a random 
> directory name is created and the zip file is stored in it. After that the 
> file will get extracted and the shape file is imported into PostGis. 
> 
> The error scenario is the following:
> For example user1 loads geo1.zip and user2 loads geo2.zip up to the server. 
> Then the two directories and files c:/abc/geo1.zip and c:/cba/geo2.zip are 
> created on the server's filesystem. Then the bug comes: my shape file reader 
> muddles up the directories and can't find the files because it puts the paths 
> together in a wrong way, e.g. c:/abc/geo2.zip.
> 
> I dont't understand why the path is created in this wrong way because the 
> requests don't share the same instance of the class ShapeFileReader (which is 
> indeed nod thread safe), they create all their own instance. 
> Perhaps an expert of you can help me to find my mistake!
> 
> Here is my code of the shape file reader:
> ###########################################
> public class ShapeFileReader {
> 
>       private static Logger logger = Logger.getLogger(ShapeFileReader.class); 
>       private URL shapeURL;
>       private ShapefileDataStore store;
>       private FeatureSource source;
>       private FeatureResults fsShape;
>       private FeatureReader reader;
>       
>       /**
>        * This method initializes the object.
>        * @param path The path to the shape file.
>        */
>       public synchronized void setShapeFilePath(String path) {
>               File file = new File(path);
> 
>               try {
>                       this.shapeURL = file.toURL();
>                       this.store = new ShapefileDataStore(this.shapeURL);
>                       String name = store.getTypeNames()[0];
>                       this.source = this.store.getFeatureSource(name);
>                       this.fsShape = this.source.getFeatures();
>                       this.reader = this.fsShape.reader();
>               } ...
            /**
>        * This method collects the geometry values from the shape file.
>        * @see GeometryBean
>        * @return A Vector of type <code>GeometryBean</code>
>        */
>       public synchronized Vector getGeometries() {
>               Vector geometries = new Vector();
>               try {
>                       this.reader = this.fsShape.reader();
> 
>                       while (this.reader.hasNext()) {
>                               Feature feature = this.reader.next();
>                               
>                               MultiPolygon polygon = (MultiPolygon) 
> feature.getDefaultGeometry();
>                               GeometryBean geometryBean = new GeometryBean();
>                               geometryBean.setMultiPolygon(polygon);
>                               geometries.add(geometryBean);
>                       }
>               }   ...
>               return geometries;
> }
> ###########################################
> 
> Here is the relevant code of the servlet which starts the import process:
> ###########################################
>  public class ShapeImportServlet extends javax.servlet.http.HttpServlet 
> implements javax.servlet.Servlet {
>       protected void doPost(HttpServletRequest request, HttpServletResponse 
> response) throws ServletException, IOException {
>               // The information about the uploaded zip file, containing the 
> directory name and the zip file name
>               UploadDataBean uploadData = (UploadDataBean) 
> session.getAttribute("uploadData");
>               this.processImport(request, uploadData);
>               ...
>       }
>       /**
>        * This method extracts the necessary information out of the request 
> and delegates
>        * the database import to a dedicated importer thread. So the servlet 
> can display
>        * the results immediately while the importer thread does its job.
>        * @param request HttpServletRequest.
>        * @param uploadData Information about the data which should be 
> uploaded.
>        */
>       private void processImport(HttpServletRequest request, UploadDataBean 
> uploadData) > {
> 
>               String directory = uploadData.getDirectoryName() + "/";
>               
>               Map parameters = request.getParameterMap();
>               
>               Set set = parameters.keySet();
>               Iterator iter = set.iterator();
>               
>               ArrayList filePaths = new ArrayList();
>               ArrayList tableNames = new ArrayList();
>               
>               ArrayList params = new ArrayList();
>               
>               //Evaluate the request parameters
>               for(Enumeration e=request.getParameterNames(); 
> e.hasMoreElements(); )
>               {
>                  params.add((String)e.nextElement());
>               } 
>               
>               String[] parameterNames = new String[params.size()];
>               
>               for (int i = 0; i < parameterNames.length; i++) {
>                       parameterNames[i] = (String) params.get(i);
>               }
>               
>               // Bring the parameter names in the right order to evaluate 
> them correctly.
>               // After sorting, the version, the pk ant the name match.
>               Arrays.sort(parameterNames);
>               for (int i = 0; i < parameterNames.length; i++) {
>                               
> tableNames.add(request.getParameter(parameterNames[i]));
>                               filePaths.add(directory + parameterNames[i]);
>                       }
>               }
>               if (workflow.equals("1")) {
>                       logger.info("User has chosen to process workflow 1");
>                       new Workflow1Thread(filePaths, tableNames, versions, 
> pks, countryID).start();
>               } else {
>                       System.out.println("---Begin DEBUG");
>                       for (int i = 0; i < filePaths.size(); i++) {
>                               System.out.print("filepath " + 
> (String)filePaths.get(i) +
>                                                                " tableName " 
> + (String) tableNames.get(i) + 
>                                                                " version " + 
> (String) versions.get(i) + "\n");
>                       }
>                       new Workflow2Thread(filePaths, tableNames, versions, 
> pks, countryID).start();
>               }
>       }
>       // This method in the workflow threads starts the reading and import of 
> the shape files:
>       protected void importGeometries() {
>                       // for every geometry table which should be imported
>                       for (int i = 0; i < this.pathToShapeFile.size(); i++) {
>                               // ShapeFileAccess mit Pfad zum File benutzen, 
> um die Eintraege zu lesen
>                               shapeFileAccess.setShapeFilePath((String) 
> this.pathToShapeFile.get(i)); // here the application gets a 
> FileNotFoundException!!
>                               Vector geometries = 
> shapeFileAccess.getGeometries();
>                       }
>       }
> }
> ###########################################
> Regards,
> Thorsten
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Geotools-gt2-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users

Reply via email to