Commit da33594c authored by Matija Obreza's avatar Matija Obreza
Browse files

FaoInstitute and WIEWS

parent 7b936beb
/**
* Copyright 2013 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package org.crophub.rest.common.model.impl;
import java.text.MessageFormat;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
import org.hibernate.annotations.Index;
@Entity
@Table(name = "faoinstitute", uniqueConstraints = @UniqueConstraint(columnNames = { "code" }))
@org.hibernate.annotations.Table(appliesTo = "faoinstitute", indexes = { @Index(columnNames = { "code" }, name = "code_FAOINSTITUTE") })
public class FaoInstitute extends GeoEntity implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = -8773002513838748431L;
private Long id;
private String code;
private String fullName;
private String type;
private String url;
private String email;
private String acronym;
private Country country;
public FaoInstitute() {
}
public FaoInstitute(final String institute, final String fullName,
final String email) {
this.code = institute;
this.fullName = fullName;
this.email = email;
}
public FaoInstitute(final String institute, final String fullName,
final String type, final String url, final String email) {
this.code = institute;
this.fullName = fullName;
this.type = type;
this.url = url;
this.email = email;
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
@Column(unique = true, nullable = false, length = 8)
public String getCode() {
return this.code;
}
public void setCode(final String institute) {
this.code = institute;
}
@Column(length = 300)
public String getFullName() {
return this.fullName;
}
public void setFullName(final String fullName) {
this.fullName = fullName;
}
@Column(length = 11)
public String getType() {
return this.type;
}
public void setType(final String type) {
this.type = type;
}
@Column(length = 300)
public String getUrl() {
return this.url;
}
public void setUrl(final String url) {
this.url = url;
}
@Column(length = 300)
public String getEmail() {
return this.email;
}
public void setEmail(final String email) {
this.email = email;
}
@Override
public String toString() {
return MessageFormat.format(
"FaoInst id={0,number,#} code={1} fullName={2}", id, code,
fullName);
}
@Column(length = 50)
public void setAcronym(final String acronym) {
this.acronym = acronym;
}
public String getAcronym() {
return acronym;
}
@ManyToOne(cascade = {}, optional = true)
@JoinColumn(name = "countryId")
public Country getCountry() {
return country;
}
public void setCountry(final Country country) {
this.country = country;
}
}
/**
* Copyright 2013 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package org.crophub.rest.common.model.impl;
import javax.persistence.MappedSuperclass;
/**
* Geo
*
* @author mobreza
*/
@MappedSuperclass
public class GeoEntity {
private Double latitude;
private Double longitude;
private Double altitude;
public Double getLatitude() {
return latitude;
}
public void setLatitude(final Double latitude) {
this.latitude = latitude;
}
public Double getLongitude() {
return longitude;
}
public void setLongitude(final Double longitude) {
this.longitude = longitude;
}
public Double getAltitude() {
return altitude;
}
public void setAltitude(final Double altitude) {
this.altitude = altitude;
}
}
/**
* Copyright 2013 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package org.crophub.rest.common.persistence.domain;
import java.util.List;
import org.crophub.rest.common.model.impl.Country;
import org.crophub.rest.common.model.impl.FaoInstitute;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
public interface FaoInstituteRepository extends
JpaRepository<FaoInstitute, Long> {
FaoInstitute findByCode(String code);
@Query("select distinct(type) from FaoInstitute")
List<String> findTypes();
List<FaoInstitute> findByCountry(Country country, Sort sort);
}
/**
* Copyright 2013 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package org.crophub.rest.common.service;
import java.io.IOException;
import java.util.List;
import org.crophub.rest.common.model.impl.Country;
import org.crophub.rest.common.model.impl.FaoInstitute;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
/**
* @author mobreza
*/
public interface InstituteService {
void updateFaoInstitutes() throws IOException;
Page<FaoInstitute> list(Pageable p);
FaoInstitute getInstitute(String wiewsCode);
List<FaoInstitute> listByCountry(Country country);
}
/**
* Copyright 2013 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package org.crophub.rest.common.service.impl;
import static org.crophub.util.NumberUtils.parseDoubleIgnore0;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.crophub.rest.common.model.impl.Country;
import org.crophub.rest.common.model.impl.FaoInstitute;
import org.crophub.rest.common.persistence.domain.CountryRepository;
import org.crophub.rest.common.persistence.domain.FaoInstituteRepository;
import org.crophub.rest.common.service.InstituteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import au.com.bytecode.opencsv.CSVReader;
@Service
@Transactional(readOnly = true)
public class InstituteServiceImpl implements InstituteService {
public static final String WIEWS_EXPORT_URL = "http://apps3.fao.org/wiews/export.zip";
public static final Log LOG = LogFactory.getLog(InstituteServiceImpl.class);
@Autowired
FaoInstituteRepository instituteRepository;
@Autowired
CountryRepository countryRepository;
@Override
public Page<FaoInstitute> list(Pageable pageable) {
return instituteRepository.findAll(pageable);
}
@Override
public FaoInstitute getInstitute(String wiewsCode) {
return instituteRepository.findByCode(wiewsCode);
}
@Override
public List<FaoInstitute> listByCountry(Country country) {
return instituteRepository.findByCountry(country, new Sort("code"));
}
/**
* Update local FaoInstitute with data from WIEWS database
*
* @throws IOException
*/
@Override
@Transactional(readOnly = false)
public void updateFaoInstitutes() throws IOException {
final HttpClient httpclient = new DefaultHttpClient();
final HttpGet httpget = new HttpGet(WIEWS_EXPORT_URL);
HttpResponse response = null;
try {
response = httpclient.execute(httpget);
} catch (final ClientProtocolException e) {
LOG.error(e.getMessage(), e);
throw new IOException(e);
}
LOG.debug(response.getStatusLine());
// Get hold of the response entity
final HttpEntity entity = response.getEntity();
LOG.debug(entity.getContentType() + " " + entity.getContentLength());
// If the response does not enclose an entity, there is no
// need
// to bother about connection release
if (entity != null) {
ZipInputStream instream = null;
try {
instream = new ZipInputStream(entity.getContent());
final ZipEntry zipEntry = instream.getNextEntry();
LOG.debug("Got entry: " + zipEntry.getName());
if (!zipEntry.getName().equals("export.txt")) {
LOG.warn("Expected export.txt, not " + zipEntry.getName());
throw new IOException("Missing export.txt");
}
final InputStreamReader inreader = new InputStreamReader(
instream);
final CSVReader reader = new CSVReader(inreader, ',', '"',
false);
String[] line = null;
while ((line = reader.readNext()) != null) {
for (int i = 0; i < line.length; i++) {
if (line[i].equals("null")
|| StringUtils.isBlank(line[i])) {
line[i] = null;
}
}
// if (StringUtils.isNotBlank(line[14])) {
// LOG.info(ArrayUtils.toString(line));
// }
final String instCode = line[0];
final String acronym = line[1];
// final String ecpaAcronym = line[2];
final String fullName = line[3];
final String type = line[4];
// final String pgrActivity = line[5];
// final String maintColl = line[6];
// final String streetPob = line[7];
// final String cityState = line[8];
// final String zipCode = line[9];
// final String phone = line[10];
// final String fax = line[11];
final String email = line[12];
final String url = line[13];
final String latitude = line[14];
final String longitude = line[15];
final String altitude = line[16];
// final String updatedOn = line[17];
// final String vInstCode = line[18];
// if (instCode.equals("NGA039")) {
// LOG.info(MessageFormat
// .format("WIEWS ORG inst={0} acronym={1} ecpa={2} fullName={3} type={4} pgr={5} city={6} zip={7} street={8}",
// instCode, acronym, ecpaAcronym,
// fullName, type, pgrActivity, cityState,
// zipCode, streetPob));
// }
FaoInstitute faoInstitute = instituteRepository
.findByCode(instCode);
if (faoInstitute == null) {
LOG.warn("Not registered: " + fullName);
faoInstitute = new FaoInstitute();
}
faoInstitute.setCode(instCode);
faoInstitute.setAcronym(acronym);
faoInstitute.setFullName(fullName);
faoInstitute.setEmail(email);
faoInstitute.setType(type);
faoInstitute.setUrl(url);
faoInstitute.setLatitude(parseDoubleIgnore0(latitude, 100));
faoInstitute
.setLongitude(parseDoubleIgnore0(longitude, 100));
faoInstitute.setAltitude(parseDoubleIgnore0(altitude, 1));
faoInstitute.setCountry(countryRepository
.findByCode3(instCode.substring(0, 3)));
instituteRepository.save(faoInstitute);
}
reader.close();
} catch (final RuntimeException ex) {
LOG.error(ex.getMessage(), ex);
httpget.abort();
} finally {
// Closing the input stream will trigger connection
// release
IOUtils.closeQuietly(instream);
}
}
LOG.info("Done importing WIEWS database");
}
}
......@@ -2,6 +2,7 @@ package org.crophub.rest.servlet.controller;
import org.crophub.rest.common.model.impl.Country;
import org.crophub.rest.common.service.GeoService;
import org.crophub.rest.common.service.InstituteService;
import org.crophub.spring.ResourceNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
......@@ -15,6 +16,9 @@ public class CountryController extends BaseController {
@Autowired
private GeoService geoService;
@Autowired
private InstituteService instituteService;
@RequestMapping
public String view(ModelMap model) {
......@@ -31,6 +35,7 @@ public class CountryController extends BaseController {
throw new ResourceNotFoundException();
}
model.addAttribute("country", country);
model.addAttribute("faoInstitutes", instituteService.listByCountry(country));
return "/country/details";
}
......
package org.crophub.rest.servlet.controller;
import org.crophub.rest.common.model.impl.FaoInstitute;
import org.crophub.rest.common.service.InstituteService;
import org.crophub.spring.ResourceNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
@RequestMapping("/wiews")
public class WiewsController extends BaseController {
@Autowired
private InstituteService instituteService;
@RequestMapping("/")
public String view(ModelMap model, @RequestParam(value = "page", required = false, defaultValue = "1") int page) {
model.addAttribute("faoInstitutes", instituteService.list(new PageRequest(page - 1, 50, new Sort("code"))));
return "/wiews/index";
}
@RequestMapping("/{wiewsCode}")
public String view(ModelMap model, @PathVariable(value = "wiewsCode") String wiewsCode) {
_logger.debug("Viewing country " + wiewsCode);
FaoInstitute faoInstitute = instituteService.getInstitute(wiewsCode);
if (faoInstitute == null) {
throw new ResourceNotFoundException();
}
model.addAttribute("faoInstitute", faoInstitute);
return "/wiews/details";
}
}
/**
* Copyright 2013 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package org.crophub.util;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public abstract class NumberUtils {
public static final Log LOG = LogFactory.getLog(NumberUtils.class);
/**
* Utility to parse doubles
*
* @param doubleString