/genesis/org.dftproject.pgv.core/src/org/dftproject/pgv/core/racp/PGVGedcom.java
Java | 345 lines | 252 code | 56 blank | 37 comment | 79 complexity | 1fb4108aff66d1110b5f83a3c7e98261 MD5 | raw file
- package org.dftproject.pgv.core.racp;
-
- import java.io.StringReader;
- import java.io.UnsupportedEncodingException;
- import java.net.URLEncoder;
- import java.text.SimpleDateFormat;
- import java.util.Arrays;
- import java.util.Calendar;
- import java.util.Collections;
- import java.util.Date;
- import java.util.HashSet;
- import java.util.LinkedList;
- import java.util.List;
- import java.util.Set;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
-
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.dftproject.gedcom.core.AbstractGedcom;
- import org.dftproject.gedcom.core.GedcomPerson;
- import org.dftproject.gedcom.core.GedcomReader;
- import org.dftproject.gedcom.core.IGedcom;
- import org.dftproject.gedcom.core.Line;
- import org.dftproject.genesis.core.http.HttpManager;
- import org.dftproject.genesis.core.persistence.IMemento;
- import org.dftproject.genesis.data.genealogy.GenealogyConstants;
- import org.dftproject.genesis.data.genealogy.ISource;
- import org.dftproject.genesis.data.genealogy.impl.SourceImpl;
- import org.dftproject.genesis.data.impl.AttributeImpl;
- import org.dftproject.pgv.core.cache.CacheManager;
- import org.dftproject.pgv.core.racp.factories.PGVGedcomFactory;
-
- public class PGVGedcom extends AbstractGedcom implements IGedcom {
-
- private static final Log log = LogFactory.getLog(PGVGedcom.class);
-
- private final static Pattern tabbedLinePattern = Pattern.compile("^([^\\t]*)\\t([^\\t]*)$");
-
- private final Session session;
- private final String gedcomId;
- private String title;
-
- public PGVGedcom(Session session, String gedcomId) {
- this(session, gedcomId, null);
- }
-
- public PGVGedcom(Session session, String gedcomId, String title) {
- this.session = session;
- this.gedcomId = gedcomId;
- this.title = title;
- }
-
- public String getUrl() {
- return session.getUrl();
- }
-
- public Session getSession() {
- return session;
- }
-
- public String getGedcomId() {
- return gedcomId;
- }
-
- public String getTitle() {
- return title;
- }
-
- protected void initTitle() {
- String response = HttpManager.getDefault().getWebPage(session.getUrl() + "client.php?action=listgedcoms&" + session.getSessionComponent());
- if (response != null) {
- String[] lines = response.split("\n");
- if (lines.length > 1 && "SUCCESS".equals(lines[0]) && !lines[1].startsWith("<")) {
- for (String line : lines) {
- Matcher matcher = tabbedLinePattern.matcher(line);
- if (matcher.matches() && gedcomId.equals(matcher.group(1))) {
- title = matcher.group(2);
- }
- }
- }
- }
- }
-
- public String getGedcomUrl() {
- try {
- return getUrl() + "index.php?ged=" + URLEncoder.encode(getGedcomId(), "UTF-8");
- } catch (UnsupportedEncodingException e) {
- return null;
- }
- }
-
- @Override
- public GedcomPerson getPerson(String id) {
- Line record = getRecord(id);
- if (record != null && "INDI".equals(record.getTag()))
- return new PGVPerson(this, id, record);
- return null;
- }
-
- public String getPersonUrl(String id) {
- try {
- return getUrl() + "individual.php?pid=" + id + "&ged=" + URLEncoder.encode(getGedcomId(), "UTF-8");
- } catch (UnsupportedEncodingException e) {
- return null;
- }
- }
-
- /**
- * Returns the record associated with <code>id</code>.
- * @return the record
- */
- public Line getRecord(String id) {
- Line[] lines = getRecords(new String[] { id });
- if (lines.length > 0) {
- if (log.isDebugEnabled())
- log.debug(lines[0].toString(true));
- return lines[0];
- }
- log.error("Failed to get record for " + id);
- return null;
- }
-
- /**
- * Returns the records associated with the <code>ids</code>.
- * @param ids an array of record ids
- * @return an array of records
- */
- public Line[] getRecords(String[] ids) {
- if (!session.isValid() && !session.connect())
- return new Line[0];
-
- List<Line> lines = new LinkedList<Line>();
-
- // First try to get the record from the cache
-
- CacheManager cacheManager = CacheManager.getDefault();
- Date today = getToday();
-
- Set<String> xrefs = new HashSet<String>(Arrays.asList(ids));
- for (String xref : ids) {
- // The cache must have a retrieval date for a record
-
- Date retrievalDate = cacheManager.getRetrievalDate(getUrl(), gedcomId, xref);
- if (retrievalDate == null)
- continue;
-
- // The retrieval date must be on or after today
-
- if (!retrievalDate.after(today) && !retrievalDate.equals(today)) {
- // If not, we must have request a list of changes today
-
- Date lastGetChanges = cacheManager.getLastGetChanges(getUrl(), gedcomId);
- if (lastGetChanges != null && !lastGetChanges.after(today) && !lastGetChanges.equals(today)) {
- // If not, request the list of changes and invalidate old
- // records
-
- Set<String> changedXrefs = getChanges(lastGetChanges, session.getSessionComponent());
- cacheManager.invalidateRecords(getUrl(), gedcomId, today, changedXrefs);
-
- // This record must not have changed since the retrieval
- // date
-
- if (changedXrefs.contains(xref)) {
- log.info(xref + " has changed since " + new SimpleDateFormat("d MMM yyyy").format(retrievalDate));
- continue;
- }
- }
- }
-
- // Get the record from the cache
-
- String record = cacheManager.getRecord(getUrl(), gedcomId, xref);
- if (record != null) {
- xrefs.remove(xref);
-
- try {
- GedcomReader reader = new GedcomReader();
- lines.addAll(reader.read(new StringReader(record)));
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
-
- // Request all cache misses
- // TODO Batch record requests with one RACP call and split the results
-
- for (String xref : xrefs) {
- Date retrieved = new Date();
- String data = getRecords(new String[] { xref }, session.getSessionComponent());
- if (data != null) {
- cacheManager.putRecord(getUrl(), gedcomId, xref, data, retrieved);
-
- try {
- GedcomReader reader = new GedcomReader();
- lines.addAll(reader.read(new StringReader(data)));
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
-
- return lines.toArray(new Line[0]);
- }
-
- /**
- * Returns a {@link Date} representing the beginning of today.
- * @return a date
- */
- protected Date getToday() {
- Calendar today = Calendar.getInstance();
- today.set(Calendar.HOUR_OF_DAY, 0);
- today.set(Calendar.MINUTE, 0);
- today.set(Calendar.SECOND, 0);
- today.set(Calendar.MILLISECOND, 0);
- return today.getTime();
- }
-
- /**
- * Returns the data for the requested records.
- * @param xrefs an array of xrefs
- * @param sessionComponent the session component
- * @return the data for the requested records, or null on failure
- */
- protected String getRecords(String[] xrefs, String sessionComponent) {
- if (xrefs == null || xrefs.length == 0 || sessionComponent == null)
- return null;
-
- StringBuilder xrefParameter = new StringBuilder();
- for (String xref : xrefs)
- xrefParameter.append(xref);
-
- String contents= null;
- try {
- contents = HttpManager.getDefault().getWebPage(getUrl() + "client.php?action=get&GEDCOM=" + URLEncoder.encode(gedcomId, "UTF-8") + "&xref=" + xrefParameter + "&" + sessionComponent);
- } catch (UnsupportedEncodingException e) {
- log.error("Failed to encode HTTP query parameter as UTF-8", e);
- }
- if (contents == null)
- return null;
-
- String[] lines = contents.split("\n");
- if (lines.length < 2)
- return null;
-
- if ("SUCCESS".equals(lines[0]) && !lines[1].startsWith("<")) {
- StringBuilder data = new StringBuilder();
- for (int i = 1; i < lines.length; i++) {
- data.append(lines[i]);
- if (i < lines.length - 1)
- data.append("\n");
- }
-
- return data.toString();
- }
-
- return null;
- }
-
- /**
- * Returns a set of xrefs for records that have changed since
- * <code>date</code>.
- * @param date a date
- * @param sessionComponent the session component
- * @return a set of xrefs for records that have changed
- */
- protected Set<String> getChanges(Date date, String sessionComponent) {
- if (date == null || sessionComponent == null)
- return Collections.emptySet();
-
- String contents = HttpManager.getDefault().getWebPage(getUrl() + "client.php?action=getchanges&GEDCOM=" + gedcomId + "&date=" + date + "&" + sessionComponent);
- if (contents == null)
- return Collections.emptySet();
-
- String[] lines = contents.split("\n");
- if (lines.length < 2)
- return Collections.emptySet();
-
- if ("SUCCESS".equals(lines[0]) && !lines[1].startsWith("<")) {
- Set<String> xrefs = new HashSet<String>();
- for (String line : lines) {
- if (!"".equals(line.trim()))
- xrefs.add(line);
- }
-
- return xrefs;
- }
-
- return Collections.emptySet();
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((gedcomId == null) ? 0 : gedcomId.hashCode());
- result = prime * result + ((session == null) ? 0 : session.hashCode());
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- final PGVGedcom other = (PGVGedcom) obj;
- if (gedcomId == null) {
- if (other.gedcomId != null)
- return false;
- } else if (!gedcomId.equals(other.gedcomId))
- return false;
- if (session == null) {
- if (other.session != null)
- return false;
- } else if (!session.equals(other.session))
- return false;
- return true;
- }
-
- public ISource asSource(String id) {
- SourceImpl source = new SourceImpl();
- source.addAttribute(new AttributeImpl(GenealogyConstants.type, "org.dftproject.pgv.source"));
- if (title == null)
- initTitle();
- if (title != null)
- source.addAttribute(new AttributeImpl(GenealogyConstants.title, title));
- source.addAttribute(new AttributeImpl(GenealogyConstants.collection, this));
- source.addAttribute(new AttributeImpl("id", id));
- return source;
- }
-
- public String getFactoryId() {
- return PGVGedcomFactory.ID;
- }
-
- public void saveState(IMemento memento) {
- memento.putString("url", session.getUrl());
- memento.putString("gedcomId", gedcomId);
- }
-
- }