View Javadoc

1   /*******************************************************************************
2    *   Gisgraphy Project 
3    * 
4    *   This library is free software; you can redistribute it and/or
5    *   modify it under the terms of the GNU Lesser General Public
6    *   License as published by the Free Software Foundation; either
7    *   version 2.1 of the License, or (at your option) any later version.
8    * 
9    *   This library is distributed in the hope that it will be useful,
10   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   *   Lesser General Public License for more details.
13   * 
14   *   You should have received a copy of the GNU Lesser General Public
15   *   License along with this library; if not, write to the Free Software
16   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
17   * 
18   *  Copyright 2008  Gisgraphy project 
19   *  David Masclet <davidmasclet@gisgraphy.com>
20   *  
21   *  
22   *******************************************************************************/
23  package com.gisgraphy.domain.geoloc.importer;
24  
25  import java.io.File;
26  import java.util.ArrayList;
27  import java.util.List;
28  
29  import org.hibernate.FlushMode;
30  import org.springframework.beans.factory.annotation.Required;
31  
32  import com.gisgraphy.domain.geoloc.entity.Adm;
33  import com.gisgraphy.domain.repository.IAdmDao;
34  import com.gisgraphy.domain.valueobject.GISSource;
35  import com.gisgraphy.domain.valueobject.NameValueDTO;
36  import com.gisgraphy.helper.GeolocHelper;
37  
38  /**
39   * Import the Adm of level 4 file. It is the first step of the adm4 import
40   * process, the import will be complete when all the datastore object will be
41   * updated by the {@link GeonamesFeatureImporter}
42   * 
43   * @author <a href="mailto:david.masclet@gisgraphy.com">David Masclet</a>
44   */
45  public class GeonamesAdm4Importer extends AbstractImporterProcessor {
46  
47      private IAdmDao admDao;
48  
49      /**
50       * Default constructor
51       */
52      public GeonamesAdm4Importer() {
53  	super();
54      }
55  
56      /*
57       * (non-Javadoc)
58       * 
59       * @see com.gisgraphy.domain.geoloc.importer.AbstractImporterProcessor#processData(java.lang.String)
60       */
61      @Override
62      protected void processData(String line) {
63  	String[] fields = line.split("\t");
64  
65  	/*
66  	 * line table has the following fields :
67  	 * --------------------------------------------------- 0 : code ; 1 :
68  	 * name
69  	 */
70  	checkNumberOfColumn(fields);
71  	Adm adm4 = new Adm(4);
72  	adm4.setLocation(GeolocHelper.createPoint(0F, 0F));
73  	adm4.setFeatureId((++AbstractImporterProcessor.nbGisInserted) * -1);
74  	adm4.setSource(GISSource.GEONAMES);
75  
76  	// process code
77  	if (!isEmptyField(fields, 0, true)) {
78  	    String[] fullAdm4Code = fields[0].split("\\.");
79  	    // check the format
80  	    if (fullAdm4Code.length != 5) {
81  		logger.warn("adm4 importer needs code with 5 fields : "
82  			+ dumpFields(fullAdm4Code) + " is not correct");
83  		return;
84  	    }
85  
86  	    if (!isEmptyField(fields, 1, true)) {
87  		adm4.setName(fields[1].trim());
88  	    }
89  
90  	    String countryCode = fullAdm4Code[0].toUpperCase();
91  	    String adm1Code = fullAdm4Code[1];
92  	    String adm2Code = fullAdm4Code[2];
93  	    String adm3Code = fullAdm4Code[3];
94  	    String adm4Code = fullAdm4Code[4];
95  
96  	    // set the code Value
97  	    if (!isEmptyField(fullAdm4Code, 0, true)) {
98  		adm4.setCountryCode(countryCode);
99  	    }
100 	    if (!isEmptyField(fullAdm4Code, 1, true)) {
101 		adm4.setAdm1Code(adm1Code);
102 	    }
103 	    if (!isEmptyField(fullAdm4Code, 2, true)) {
104 		adm4.setAdm2Code(adm2Code);
105 	    }
106 	    if (!isEmptyField(fullAdm4Code, 3, true)) {
107 		adm4.setAdm3Code(adm3Code);
108 	    }
109 	    if (!isEmptyField(fullAdm4Code, 4, true)) {
110 		adm4.setAdm4Code(adm4Code);
111 	    }
112 
113 	    Adm duplicate = this.admDao.getAdm4(countryCode, adm1Code,
114 		    adm2Code, adm3Code, adm4Code);
115 	    if (duplicate != null) {
116 		logger
117 			.warn(adm4
118 				+ " will not be saved because it is duplicate (same codes) with "
119 				+ duplicate);
120 		return;
121 	    }
122 
123 	    // try to get the parent Adm3
124 	    Adm adm3 = null;
125 
126 	    adm3 = this.admDao.getAdm3(countryCode, adm1Code, adm2Code,
127 		    adm3Code);
128 
129 	    // if found add to Adm3Childs
130 	    if (adm3 == null) {
131 		logger.warn("could not find adm3 for " + countryCode + "."
132 			+ adm1Code + "." + adm2Code + "." + adm3Code
133 			+ " for the adm4 " + adm4);
134 		return;
135 	    } else {
136 		adm3.addChild(adm4);
137 	    }
138 	}
139 
140 	if (!isEmptyField(fields, 2, false)) {
141 	    adm4.setAsciiName(fields[2].trim());
142 	}
143 
144 	// fallback if asciiName is not null and name is null
145 	if (isEmptyField(fields, 1, false) && !isEmptyField(fields, 2, false)) {
146 	    adm4.setName(fields[2].trim());
147 	}
148 
149 	this.admDao.save(adm4);
150 
151     }
152     
153     /* (non-Javadoc)
154      * @see com.gisgraphy.domain.geoloc.importer.AbstractImporterProcessor#shouldBeSkiped()
155      */
156     @Override
157     protected boolean shouldBeSkipped() {
158 	return !importerConfig.isGeonamesImporterEnabled();
159     }
160 
161     /*
162      * (non-Javadoc)
163      * 
164      * @see com.gisgraphy.domain.geoloc.importer.AbstractImporterProcessor#shouldIgnoreFirstLine()
165      */
166     @Override
167     protected boolean shouldIgnoreFirstLine() {
168 	return false;
169     }
170 
171     /*
172      * (non-Javadoc)
173      * 
174      * @see com.gisgraphy.domain.geoloc.importer.AbstractImporterProcessor#shouldIgnoreComments()
175      */
176     @Override
177     protected boolean shouldIgnoreComments() {
178 	return true;
179     }
180 
181     /*
182      * (non-Javadoc)
183      * 
184      * @see com.gisgraphy.domain.geoloc.importer.AbstractImporterProcessor#setCommitFlushMode()
185      */
186     @Override
187     protected void setCommitFlushMode() {
188 	this.admDao.setFlushMode(FlushMode.COMMIT);
189     }
190 
191     /*
192      * (non-Javadoc)
193      * 
194      * @see com.gisgraphy.domain.geoloc.importer.AbstractImporterProcessor#flushAndClear()
195      */
196     @Override
197     protected void flushAndClear() {
198 	this.admDao.flushAndClear();
199     }
200 
201     /*
202      * (non-Javadoc)
203      * 
204      * @see com.gisgraphy.domain.geoloc.importer.AbstractImporterProcessor#getNumberOfColumns()
205      */
206     @Override
207     protected int getNumberOfColumns() {
208 	return 2;
209     }
210 
211     /**
212      * @param admDao
213      *                The admDao to set
214      */
215     @Required
216     public void setAdmDao(IAdmDao admDao) {
217 	this.admDao = admDao;
218     }
219 
220     /*
221      * (non-Javadoc)
222      * 
223      * @see com.gisgraphy.domain.geoloc.importer.AbstractImporterProcessor#getFiles()
224      */
225     @Override
226     protected File[] getFiles() {
227 	File[] files = new File[1];
228 	files[0] = new File(importerConfig.getGeonamesDir()
229 		+ importerConfig.getAdm4FileName());
230 	return files;
231     }
232 
233     /*
234      * (non-Javadoc)
235      * 
236      * @see com.gisgraphy.domain.geoloc.importer.AbstractImporterProcessor#getMaxInsertsBeforeFlush()
237      */
238     @Override
239     protected int getMaxInsertsBeforeFlush() {
240 	// we commit each times because we don't want duplicate adm and the
241 	// cache is NONSTRICT_READ_WRITE (assynchronous)
242 	return 1;
243     }
244 
245     /*
246      * (non-Javadoc)
247      * 
248      * @see com.gisgraphy.domain.geoloc.importer.IGeonamesProcessor#rollback()
249      */
250     public List<NameValueDTO<Integer>> rollback() {
251 	List<NameValueDTO<Integer>> deletedObjectInfo = new ArrayList<NameValueDTO<Integer>>();
252 	logger.info("deleting adm4...");
253 	int deletedadm = admDao.deleteAllByLevel(4);
254 	if (deletedadm != 0) {
255 	    deletedObjectInfo
256 		    .add(new NameValueDTO<Integer>("ADM4", deletedadm));
257 	}
258 	logger.info(deletedadm + " adm4s have been deleted");
259 	resetStatusFields();
260 	return deletedObjectInfo;
261     }
262 
263 }