/* See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* Esri Inc. licenses this file to You 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 com.esri.gpt.control.georss;
import com.esri.gpt.catalog.search.OpenSearchProperties;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.esri.gpt.catalog.search.ResourceLink;
import com.esri.gpt.catalog.search.SearchResultRecord;
import com.esri.gpt.catalog.search.SearchResultRecords;
import com.esri.gpt.framework.jsf.MessageBroker;
import com.esri.gpt.framework.util.Val;
import java.io.BufferedWriter;
/**
* ATOM feed writer.
*/
public class AtomFeedWriter implements FeedWriter {
/** The LOGGER. */
private static Logger LOGGER = Logger.getLogger(AtomFeedWriter.class.getName());
/** The DAT e_ forma t_ pattern. */
private final String DATE_FORMAT_PATTERN = "yyyy-MM-dd";
/** The TIM e_ forma t_ pattern. */
private final String TIME_FORMAT_PATTERN = "kk:mm:ss";
/** The _writer. */
private PrintWriter _writer;
/** The _entry base url. */
private String _entryBaseUrl = null;
/** The _target. */
private RecordSnippetWriter.Target _target = RecordSnippetWriter.Target.blank;
/** The _message broker. */
private MessageBroker _messageBroker = null;
/** line separator */
private String lineSeparator;
// constructors ================================================================
/**
* Constructor.
*
* @param writer the writer
*/
public AtomFeedWriter(PrintWriter writer) {
_writer = writer;
lineSeparator = (String) java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("line.separator"));
}
/**
* Constructor.
*
* @param writer the writer
* @param entryBaseUrl provider URL
*/
public AtomFeedWriter(PrintWriter writer, String entryBaseUrl) {
_writer = writer;
_entryBaseUrl = entryBaseUrl;
lineSeparator = (String) java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction("line.separator"));
}
// properties
/**
* Sets the entry base url.
*
* @param url the new entry base url
*/
public void setEntryBaseUrl(String url) {
_entryBaseUrl = url;
}
// ==================================================================
/**
* Gets the entry base url.
*
* @return Base URL
*/
public String getEntryBaseUrl() {
return _entryBaseUrl;
}
/**
* Gets links target.
*
* @return links targets
*/
public RecordSnippetWriter.Target getTarget() {
return _target;
}
/**
* Sets links target.
*
* @param target
* links target
*/
public void setTarget(RecordSnippetWriter.Target target) {
_target = target;
}
/**
* Gets the Message Broker.
*
* @return message broker
*/
public MessageBroker getMessageBroker() {
_messageBroker = (_messageBroker != null) ? _messageBroker
: new MessageBroker();
return _messageBroker;
}
/**
* Sets the Message Broker.
*
* @param broker the new _message broker
*/
public void set_messageBroker(MessageBroker broker) {
_messageBroker = broker;
}
// methods
// ==================================================================
/**
* Write Atom Feed.
*
* @param records records to write
*/
@Override
public void write(IFeedRecords records) {
if (_writer == null)
return;
AtomFeed af = new AtomFeed();
String sTitle = _messageBroker.retrieveMessage("catalog.rest.title");
String sDescription = _messageBroker.retrieveMessage("catalog.rest.description");
String sCopyright = _messageBroker.retrieveMessage("catalog.rest.copyright");
String sGenerator = _messageBroker.retrieveMessage("catalog.rest.generator");
if (sTitle.startsWith("???")) sTitle = "";
if (sDescription.startsWith("???")) sDescription = "";
if (sCopyright.startsWith("???")) sCopyright = "";
if (sGenerator.startsWith("???")) sGenerator = "";
af.setTitle(sTitle);
af.setDescription(sDescription);
af.setAuthor(sGenerator);
af.setCopyright(sCopyright);
af.setLink(getEntryBaseUrl());
af.setId(getEntryBaseUrl());
af.setUpdated(new Date());
af.setOsProps(records.getOpenSearchProperties());
for (IFeedRecord record : records) {
AtomEntry ae = new AtomEntry();
ae.setId(record.getUuid());
ae.setPublished(record.getModfiedDate());
ae.setTitle(record.getTitle());
ae.setSummary(record.getAbstract());
for (ResourceLink link : record.getResourceLinks()) {
ae.addResourceLink(link);
}
ae.addResourceLink(record.getResourceLinks().getThumbnail());
if (record.getEnvelope() != null) {
ae.setMinx(record.getEnvelope().getMinX());
ae.setMiny(record.getEnvelope().getMinY());
ae.setMaxx(record.getEnvelope().getMaxX());
ae.setMaxy(record.getEnvelope().getMaxY());
}
af.addEntry(ae);
}
af.WriteTo(_writer);
}
// Private classes
// ==================================================================
/**
* Represents an Atom Entry.
*/
public class AtomEntry {
/** The ENTIT y_ ope n_ tag. */
private final String ENTITY_OPEN_TAG = "<entry>";
/** The ENTIT y_ clos e_ tag. */
private final String ENTITY_CLOSE_TAG = "</entry>";
/** The TITL e_ ope n_ tag. */
private final String TITLE_OPEN_TAG = "<title>";
/** The TITL e_ clos e_ tag. */
private final String TITLE_CLOSE_TAG = "</title>";
// private final String LINK_TAG = "<link type=\"text/html\" href=\"?\"/>";
/** The LIN k_ tag. */
private final String LINK_TAG = "<link href=\"?\"/>";
/** The I d_ ope n_ tag. */
private final String ID_OPEN_TAG = "<id>";
/** The I d_ clos e_ tag. */
private final String ID_CLOSE_TAG = "</id>";
/** The UPDATE d_ ope n_ tag. */
private final String UPDATED_OPEN_TAG = "<updated>";
/** The UPDATE d_ clos e_ tag. */
private final String UPDATED_CLOSE_TAG = "</updated>";
/** The SUMMAR y_ ope n_ tag. */
private final String SUMMARY_OPEN_TAG = "<summary>";
/** The SUMMAR y_ clos e_ tag. */
private final String SUMMARY_CLOSE_TAG = "</summary>";
/** The BO x_ ope n_ tag. */
private final String BOX_OPEN_TAG = "<georss:box>";
/** The BO x_ clos e_ tag. */
private final String BOX_CLOSE_TAG = "</georss:box>";
/** The RES t_ fin d_ pattern. */
private final String REST_FIND_PATTERN = "/rest/document/";
/** The _id. */
private String _id = null;
/** The _title. */
private String _title = null;
/** The _link. */
private LinkedList<String> _link = null;
/** The _published. */
private Date _published = null;
/** The _summary. */
private String _summary = null;
/** The _minx. */
private double _minx = 0;
/** The _miny. */
private double _miny = 0;
/** The _maxx. */
private double _maxx = 0;
/** The _maxy. */
private double _maxy = 0;
/** The custom elements. */
private String customElements;
// methods
// ==================================================================
/**
* Gets the minx.
*
* @return the minx
*/
public double getMinx() {
return _minx;
}
/**
* Gets the miny.
*
* @return the miny
*/
public double getMiny() {
return _miny;
}
/**
* Gets the maxx.
*
* @return the maxx
*/
public double getMaxx() {
return _maxx;
}
/**
* Gets the maxy.
*
* @return the maxy
*/
public double getMaxy() {
return _maxy;
}
/**
* Sets the minx.
*
* @param _minx the new minx
*/
public void setMinx(double _minx) {
this._minx = _minx;
}
/**
* Sets the miny.
*
* @param _miny the new miny
*/
public void setMiny(double _miny) {
this._miny = _miny;
}
/**
* Sets the maxx.
*
* @param _maxx the new maxx
*/
public void setMaxx(double _maxx) {
this._maxx = _maxx;
}
/**
* Sets the maxy.
*
* @param _maxy the new maxy
*/
public void setMaxy(double _maxy) {
this._maxy = _maxy;
}
/**
* Gets the id.
*
* @return the id
*/
public String getId() {
return _id;
}
/**
* Gets the title.
*
* @return the title
*/
public String getTitle() {
return _title;
}
/**
* Gets the links.
*
* @return the links
*/
public LinkedList<String> getLinks() {
return _link;
}
/**
* Gets the published.
*
* @return the published
*/
public Date getPublished() {
return _published;
}
/**
* Gets the summary.
*
* @return the summary
*/
public String getSummary() {
return _summary;
}
/**
* Sets the id.
*
* @param id the new id
*/
public void setId(String id) {
this._id = id;
}
/**
* Sets the title.
*
* @param title the new title
*/
public void setTitle(String title) {
_title = title;
}
/**
* Sets the published.
*
* @param published the new published
*/
public void setPublished(Date published) {
_published = published;
}
/**
* Sets the summary.
*
* @param summary the new summary
*/
public void setSummary(String summary) {
_summary = summary;
}
/**
* Gets the custom elements.
*
* @return the custom elements
*/
public String getCustomElements() {
return customElements;
}
/**
* Sets the custom elements.
*
* @param customElements the new custom elements
*/
public void setCustomElements(String customElements) {
this.customElements = customElements;
}
/**
* Adds the resource link.
*
* @param resourcelink the resourcelink
*/
public void addResourceLink(ResourceLink resourcelink) {
if (resourcelink == null)
return;
if (_link == null)
_link = new LinkedList<String>();
if (resourcelink.getUrl() != null && resourcelink.getUrl().length() > 0)
_link.add(resourcelink.getUrl());
}
/**
* Write to.
*
* @param writer the writer
*/
public void WriteTo(java.io.Writer writer) {
String data = "";
if (writer == null)
return;
try {
writer.append(ENTITY_OPEN_TAG+lineSeparator);
if (getTitle() != null) {
try {
data = TITLE_OPEN_TAG + Val.escapeXml(getTitle()) + TITLE_CLOSE_TAG;
writer.append("\t"+data+lineSeparator);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "", e);
}
}
// add the rest of links if they exist
if (getLinks() != null) {
for (String lnk : getLinks()) {
try {
data = LINK_TAG.replace("?", Val.escapeXml(lnk));
writer.append("\t"+data+lineSeparator);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "", e);
}
}
}
if (getId() != null) {
try {
data = Val.escapeXml(getId());
data = ID_OPEN_TAG + "urn:uuid:" + data.substring(1, data.length() - 1)
+ ID_CLOSE_TAG;
writer.append("\t"+data+lineSeparator);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "", e);
}
}
if (getPublished() != null) {
try {
SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT_PATTERN);
data = format.format(getPublished());
format = new SimpleDateFormat(TIME_FORMAT_PATTERN);
data = data + "T" + format.format(getPublished()) + "Z";
data = UPDATED_OPEN_TAG + data + UPDATED_CLOSE_TAG;
writer.append("\t"+data+lineSeparator);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "", e);
}
}
if (getSummary() != null) {
try {
data = SUMMARY_OPEN_TAG + Val.escapeXml(getSummary())
+ SUMMARY_CLOSE_TAG;
writer.append("\t"+data+lineSeparator);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "", e);
}
}
/*if (hasEnvelope()) {
try {
data = BOX_OPEN_TAG + getMiny() + " " + getMinx() + " " + getMaxy()
+ " " + getMaxx() + BOX_CLOSE_TAG;
writer.append("\t"+data+lineSeparator);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "", e);
}
}*/
if( getCustomElements() != null) {
writer.append("\t"+Val.chkStr(getCustomElements())+lineSeparator);
}
writer.append(ENTITY_CLOSE_TAG+lineSeparator);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "", e);
}
}
/**
* Checks for envelope.
*
* @return true, if successful
*/
private boolean hasEnvelope() {
return !(getMinx() == 0 && getMiny() == 0 && getMaxx() == 0 && getMaxy() == 0);
}
}
/**
* Represents an Atom Feed.
*/
public class AtomFeed {
/** The ATO m_ header. */
private final String ATOM_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
/** The ATO m_ roo t_ ope n_ tag. */
private String ATOM_ROOT_OPEN_TAG = "<feed xmlns=\"http://www.w3.org/2005/Atom\" xmlns:georss=\"http://www.georss.org/georss\" xmlns:opensearch=\"http://a9.com/-/spec/opensearch/1.1/\">";
/** The ATO m_ roo t_ clos e_ tag. */
private final String ATOM_ROOT_CLOSE_TAG = "</feed>";
/** The COMMEN t_ ope n_ tag. */
private final String COMMENT_OPEN_TAG = "<!--";
/** The COMMEN t_ clos e_ tag. */
private final String COMMENT_CLOSE_TAG = "-->";
/** The TITLE open tag. */
private final String TITLE_OPEN_TAG = "<title>";
/** The TITLE close tag. */
private final String TITLE_CLOSE_TAG = "</title>";
/** The AUTHOR open tag. */
private final String AUTHOR_OPEN_TAG = "<author><name>";
/** The AUTHOR clos e_ tag. */
private final String AUTHOR_CLOSE_TAG = "</name></author>";
/** The LIN k_ tag. */
private final String LINK_TAG = "<link rel=\"self\" href=\"?\"/>";
/** The UPDATED open tag. */
private final String UPDATED_OPEN_TAG = "<updated>";
/** The UPDATED close tag. */
private final String UPDATED_CLOSE_TAG = "</updated>";
/** The ID open tag. */
private final String ID_OPEN_TAG = "<id>";
/** The ID close_ tag. */
private final String ID_CLOSE_TAG = "</id>";
/** The TOTAL results open_ tag. */
private final String TOTAL_RESULTS_OPEN_TAG = "<opensearch:totalResults>";
/** The TOTA l_ result s_ clos e_ tag. */
private final String TOTAL_RESULTS_CLOSE_TAG = "</opensearch:totalResults>";
/** The STAR t_ inde x_ ope n_ tag. */
private final String START_INDEX_OPEN_TAG = "<opensearch:startIndex>";
/** The STAR t_ inde x_ clos e_ tag. */
private final String START_INDEX_CLOSE_TAG = "</opensearch:startIndex>";
/** The ITEM s_ pe r_ pag e_ ope n_ tag. */
private final String ITEMS_PER_PAGE_OPEN_TAG = "<opensearch:itemsPerPage>";
/** The ITEM s_ pe r_ pag e_ clos e_ tag. */
private final String ITEMS_PER_PAGE_CLOSE_TAG = "</opensearch:itemsPerPage>";
/** The _copyright. */
private String _copyright = null;
/** The _description. */
private String _description = null;
/** The _title. */
private String _title = null;
/** The _link. */
private String _link = null;
/** The _updated. */
private Date _updated = null;
/** The _author. */
private String _author = null;
/** The _id. */
private String _id = null;
/** The os props. */
private OpenSearchProperties osProps = null;
/** The _entries. */
private LinkedList<AtomEntry> _entries = null;
/**
* Instantiates a new atom feed.
*/
public AtomFeed() {
_entries = new LinkedList<AtomEntry>();
}
/**
* Adds the entry.
*
* @param ae the ae
*/
public void addEntry(AtomEntry ae) {
if (ae != null) {
_entries.add(ae);
}
}
/**
* Gets the copyright.
*
* @return the copyright
*/
public String getCopyright() {
return _copyright;
}
/**
* Gets the description.
*
* @return the description
*/
public String getDescription() {
return _description;
}
/**
* Gets the author.
*
* @return the author
*/
public String getAuthor() {
return _author;
}
/**
* Entries.
*
* @return the linked list
*/
public LinkedList<AtomEntry> Entries() {
return _entries;
}
/**
* Gets the title.
*
* @return the title
*/
public String getTitle() {
return _title;
}
/**
* Gets the link.
*
* @return the link
*/
public String getLink() {
return _link;
}
/**
* Gets the updated.
*
* @return the updated
*/
public Date getUpdated() {
return _updated;
}
/**
* Gets the id.
*
* @return the id
*/
public String getId() {
return _id;
}
/**
* Gets the os props.
*
* @return the os props
*/
public OpenSearchProperties getOsProps() {
return osProps;
}
/**
* Sets the copyright.
*
* @param copyright the new copyright
*/
public void setCopyright(String copyright) {
this._copyright = copyright;
}
/**
* Sets the description.
*
* @param description the new description
*/
public void setDescription(String description) {
this._description = description;
}
/**
* Sets the author.
*
* @param author the new author
*/
public void setAuthor(String author) {
this._author = author;
}
/**
* Sets the title.
*
* @param title the new title
*/
public void setTitle(String title) {
this._title = title;
}
/**
* Sets the link.
*
* @param link the new link
*/
public void setLink(String link) {
this._link = link;
}
/**
* Sets the updated.
*
* @param updated the new updated
*/
public void setUpdated(Date updated) {
this._updated = updated;
}
/**
* Sets the id.
*
* @param id the new id
*/
public void setId(String id) {
this._id = id;
}
/**
* Sets the os props.
*
* @param osProps the new os props
*/
public void setOsProps(OpenSearchProperties osProps) {
this.osProps = osProps;
}
/**
* Gets the info.
*
* @return the info
*/
public String getInfo() {
StringBuffer sb = new StringBuffer();
if (getDescription() != null) {
sb.append("Description: " + getDescription() + "\n");
}
if (getCopyright() != null) {
sb.append("Copyright: " + getCopyright() + "\n");
}
return sb.toString();
}
/**
* Write preamble.
*
* @param writer the writer
* @throws IOException Signals that an I/O exception has occurred.
*/
public void writePreamble(java.io.Writer writer) throws IOException {
String data = null;
if (writer == null)
return;
writer.append(ATOM_HEADER+lineSeparator);
writer.append(ATOM_ROOT_OPEN_TAG+lineSeparator);
if (getInfo().length() > 0) {
try {
data = Val.escapeXml(getInfo());
writer.append(COMMENT_OPEN_TAG +lineSeparator+ data + COMMENT_CLOSE_TAG+lineSeparator);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "", e);
}
}
if (getId() != null) {
try {
data = Val.escapeXml(getId());
writer.append(ID_OPEN_TAG + data + ID_CLOSE_TAG+lineSeparator);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "", e);
}
}
if (getTitle() != null) {
try {
data = Val.escapeXml(getTitle());
writer.append(TITLE_OPEN_TAG + data + TITLE_CLOSE_TAG+lineSeparator);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "", e);
}
}
if (getLink() != null) {
try {
data = LINK_TAG.replace("?", Val.escapeXml(getEntryBaseUrl()));
writer.append(data+lineSeparator);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "", e);
}
}
if (getAuthor() != null) {
try {
data = Val.escapeXml(getAuthor());
writer.append(AUTHOR_OPEN_TAG + data + AUTHOR_CLOSE_TAG+lineSeparator);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "", e);
}
}
if (getUpdated() != null) {
try {
SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT_PATTERN);
data = format.format(getUpdated());
format = new SimpleDateFormat(TIME_FORMAT_PATTERN);
data = data + "T" + format.format(getUpdated()) + "Z";
data = UPDATED_OPEN_TAG + data + UPDATED_CLOSE_TAG;
writer.append(data+lineSeparator);
} catch (Exception e) {
LOGGER.log(Level.WARNING, "", e);
}
}
if (getOsProps() != null) {
_writer.println(TOTAL_RESULTS_OPEN_TAG + getOsProps().getNumberOfHits()
+ TOTAL_RESULTS_CLOSE_TAG);
_writer.println(START_INDEX_OPEN_TAG + getOsProps().getStartRecord()
+ START_INDEX_CLOSE_TAG);
_writer.println(ITEMS_PER_PAGE_OPEN_TAG + getOsProps().getRecordsPerPage()
+ ITEMS_PER_PAGE_CLOSE_TAG);
}
}
/**
* Write end.
*
* @param writer the writer
* @throws IOException Signals that an I/O exception has occurred.
*/
public void writeEnd(java.io.Writer writer) throws IOException {
writer.write(ATOM_ROOT_CLOSE_TAG+lineSeparator);
}
/**
* Write to.
*
* @param writer the writer
*/
public void WriteTo(java.io.Writer writer) {
String data = null;
if (writer == null)
return;
try {
writePreamble(writer);
for (AtomEntry ae : Entries()) {
ae.WriteTo(writer);
}
writeEnd(writer);
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "", e);
}
}
public void addStringToXmlHeader(String replace) {
ATOM_ROOT_OPEN_TAG = ATOM_ROOT_OPEN_TAG.replace(">" , replace + ">");
}
}
}