Java tutorial
//=== Copyright (C) 2001-2005 Food and Agriculture Organization of the //=== United Nations (FAO-UN), United Nations World Food Programme (WFP) //=== and United Nations Environment Programme (UNEP) //=== //=== This program is free software; you can redistribute it and/or modify //=== it under the terms of the GNU General Public License as published by //=== the Free Software Foundation; either version 2 of the License, or (at //=== your option) any later version. //=== //=== This program is distributed in the hope that it will be useful, but //=== WITHOUT ANY WARRANTY; without even the implied warranty of //=== MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //=== General Public License for more details. //=== //=== You should have received a copy of the GNU General Public License //=== along with this program; if not, write to the Free Software //=== Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //=== //=== Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2, //=== Rome - Italy. email: GeoNetwork@fao.org //============================================================================== package org.fao.geonet.kernel; import org.fao.geonet.constants.Geonet.Namespaces; import org.fao.geonet.languages.IsoLanguagesMapper; import org.jdom.Content; import org.jdom.Element; import org.springframework.util.StringUtils; import java.util.*; import org.apache.commons.httpclient.util.URIUtil; import org.apache.commons.httpclient.URIException; /** * TODO javadoc. * */ public class KeywordBean { private int id; private String code; private String coordEast = ""; private String coordWest = ""; private String coordSouth = ""; private String coordNorth = ""; private String thesaurusKey; private boolean selected; private String thesaurusTitle; private String thesaurusDate; private String downloadUrl; private String keywordUrl; /** * A Hashmap of all the languages available in this keyword * * Parameters are: Language, Label */ private final Map<String, String> values = new LinkedHashMap<String, String>(); private final Map<String, String> definitions = new LinkedHashMap<String, String>(); private IsoLanguagesMapper isoLanguageMapper; private String defaultLang; private String broader; /** * Create keyword bean with the default IsoLanguageMapper */ public KeywordBean() { this(null); } public KeywordBean(IsoLanguagesMapper isoLangMapper) { this.isoLanguageMapper = isoLangMapper; } public KeywordBean setThesaurusInfo(Thesaurus thesaurus) { this.thesaurusKey = thesaurus.getKey(); this.thesaurusDate = thesaurus.getDate(); this.thesaurusTitle = thesaurus.getTitle(); return this; } public boolean isSelected() { return selected; } public KeywordBean setSelected(boolean selected) { this.selected = selected; return this; } public String getThesaurusKey() { return thesaurusKey; } public KeywordBean setThesaurusKey(String thesaurusKey) { this.thesaurusKey = thesaurusKey; return this; } public String getThesaurusTitle() { return thesaurusTitle; } public void setThesaurusTitle(String thesaurusTitle) { this.thesaurusTitle = thesaurusTitle; } public String getThesaurusDate() { return thesaurusDate; } public void setThesaurusDate(String thesaurusDate) { this.thesaurusDate = thesaurusDate; } public KeywordBean setKeywordUrl(String keywordUrl) { this.keywordUrl = keywordUrl; return this; } public String getKeywordUrl() { return keywordUrl; } /** * Return default language. The default language is determined when creating the bean. * In some cases the language is explicitly declared if not then it is the context language * if there is no context available it is Geonet.DEFAULT_LANGUAGE * * @return the default language */ public String getDefaultLang() { return defaultLang; } public KeywordBean setDefaultLang(String defaultLang) { this.defaultLang = defaultLang; return this; } /** * Get the "default" value. The default language is determined when creating the * bean. Since often keyword beans have a single language this will return the only value * * @return return default value */ public String getDefaultValue() { return values.get(defaultLang); } /** * Return an <em>unmodifiable</em> map of values. Key is the 3 letter code language * * @return all definitions */ public Map<String, String> getValues() { return Collections.unmodifiableMap(values); } /** * Set a definition for the specified language * * @param definition the new definition * @param lang the language to set, can be 2 or 3 letter language code * * @return this keyword bean */ public KeywordBean setValue(String value, String lang) { if (defaultLang == null) { defaultLang = to3CharLang(lang); } values.put(to3CharLang(lang), value); return this; } /** * Get the "default" definition. The default language is determined when creating the * bean. Since often keyword beans have a single language this will return the only definition * * @return return default definition */ public String getDefaultDefinition() { return definitions.get(defaultLang); } /** * Return an <em>unmodifiable</em> map of definitions. Key is the 3 letter code language * * @return all definitions */ public Map<String, String> getDefinitions() { return Collections.unmodifiableMap(definitions); } /** * Set a definition for the specified language * * @param definition the new definition * @param lang the language to set * * @return this keyword */ public KeywordBean setDefinition(String definition, String lang) { if (defaultLang == null) { defaultLang = to3CharLang(lang); } definitions.put(to3CharLang(lang), definition); return this; } public int getId() { return id; } public KeywordBean setId(int id) { this.id = id; return this; } /** * Returns the URI of the keyword concept. */ public String getUriCode() { return code; } /** * TODO javadoc. * * @return */ public String getRelativeCode() { if (code == null) { return ""; } else if (code.contains("#")) return code.split("#")[1]; else return code; } /** * TODO javadoc. * * @return */ public String getNameSpaceCode() { if (code == null) { return "#"; } else if (code.contains("#")) { String[] parts = code.split("#", 2); return parts[0] + "#"; } else { return "#"; } } public KeywordBean setUriCode(String code) { this.code = code; return this; } private String asString(String s) { return s == null ? "" : s; } public String getCoordEast() { return asString(coordEast); } public KeywordBean setCoordEast(String coordEast) { this.coordEast = asString(coordEast); return this; } public String getCoordNorth() { return asString(coordNorth); } public KeywordBean setCoordNorth(String coordNorth) { this.coordNorth = asString(coordNorth); return this; } public String getCoordWest() { return asString(coordWest); } public KeywordBean setCoordWest(String coordWest) { this.coordWest = asString(coordWest); return this; } public String getCoordSouth() { return asString(coordSouth); } public KeywordBean setCoordSouth(String coordSouth) { this.coordSouth = asString(coordSouth); return this; } /** * TODO javadoc. * * @return */ public String getType() { int tmpDotIndex = thesaurusKey.indexOf('.'); return thesaurusKey.substring(tmpDotIndex + 1, thesaurusKey.indexOf(".", tmpDotIndex + 1)); } public String getThesaurusType() { return org.apache.commons.lang.StringUtils.substringBefore(thesaurusKey, "."); } /** * Transforms a KeywordBean object into its iso19139 representation. * * <pre> * <gmd:keyword xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href=""> * <gmx:Anchor xlink:href="link_to_keyword_generator">A KEYWORD GENERATED BY XLINK SERVICE</gco:Anchor> * </gmd:keyword> * <gmd:type> * <gmd:MD_KeywordTypeCode codeList="http://www.isotc211.org/2005/resources/codeList.xml#MD_KeywordTypeCode" codeListValue="TYPE"/> * </gmd:type> * <gmd:thesaurusName> * <gmd:CI_Citation> * <gmd:title> * <gco:CharacterString>THESAURUS NAME</gco:CharacterString> * </gmd:title> * <gmd:date gco:nilReason="unknown"/> * <gmd:identifier> * <gmd:MD_Identifier> * <gmd:code> * <gmx:Anchor xlink:href="http://localhost:8080/geonetwork/srv/eng/metadata.show?uuid=bc44a748-f1a1-4775-9395-a4a6d8bb8df6">register.theme.bc44a748-f1a1-4775-9395-a4a6d8bb8df6</gmx:Anchor> * </gmd:code> * </gmd:MD_Identifier> * </gmd:identifier> * </gmd:CI_Citation> * </gmd:thesaurusName> * </pre> * * @return an iso19139 representation of the keyword */ public Element getIso19139() { Element ele = new Element("MD_Keywords", Namespaces.GMD); Element el = new Element("keyword", Namespaces.GMD); Element an = new Element("Anchor", Namespaces.GMX); Element cs = new Element("CharacterString", Namespaces.GCO); if (getUriCode() != null && getUriCode().length() != 0) { try { an.setText(getDefaultValue()); an.setAttribute("href", URIUtil.encodeQuery(keywordUrl + getUriCode()), Namespaces.XLINK); el.addContent(an); } catch (URIException e) { // what to do here? Just add the value cs.setText(getDefaultValue()); el.addContent(cs); } } else { cs.setText(getDefaultValue()); el.addContent(cs); } Element type = KeywordBean.createKeywordTypeElt(this); Element thesaurusName = KeywordBean.createThesaurusNameElt(this); ele.addContent(el); ele.addContent(type); ele.addContent(thesaurusName); return ele; } /** * Transforms a list of KeywordBean object into its iso19139 representation. * * <pre> * <gmd:MD_Keywords> * <gmd:keyword> * <gmx:Anchor xlink:href="link_to_keyword_generator">Keyword 1</gmx:Anchor> * </gmd:keyword> * <gmd:keyword> * <gmx:Anchor xlink:href="link_to_keyword_generator">Keyword 2</gmx:Anchor> * </gmd:keyword> * <gmd:type> * <gmd:MD_KeywordTypeCode codeList="http://www.isotc211.org/2005/resources/codeList.xml#MD_KeywordTypeCode" codeListValue="TYPE"/> * </gmd:type> * <gmd:thesaurusName> * <gmd:CI_Citation id="geonetwork.thesaurus.register.theme.bc44a748-f1a1-4775-9395-a4a6d8bb8df6"> * <gmd:title> * <gco:CharacterString>THESAURUS NAME</gco:CharacterString> * </gmd:title> * <gmd:date gco:nilReason="unknown"/> * <gmd:identifier> * <gmd:MD_Identifier> * <gmd:code> * <gmx:Anchor xlink:href="http://localhost:8080/geonetwork/srv/eng/metadata.show?uuid=bc44a748-f1a1-4775-9395-a4a6d8bb8df6">register.theme.bc44a748-f1a1-4775-9395-a4a6d8bb8df6</gmx:Anchor> * </gmd:code> * </gmd:MD_Identifier> * </gmd:identifier> * </gmd:CI_Citation> * </gmd:thesaurusName> * </gmd:MD_Keywords> * </pre> * * * @param kbList * @return a complex iso19139 representation of the keyword */ public static Element getComplexIso19139Elt(List<KeywordBean> kbList) { Element root = new Element("MD_Keywords", Namespaces.GMD); Element cs = new Element("CharacterString", Namespaces.GCO); Element an = new Element("Anchor", Namespaces.GMX); List<Element> keywords = new ArrayList<Element>(); Element type = null; Element thesaurusName = null; for (KeywordBean kb : kbList) { Element keyword = new Element("keyword", Namespaces.GMD); if (kb.getUriCode() != null && kb.getUriCode().length() != 0) { try { an.setText(kb.getDefaultValue()); an.setAttribute("href", URIUtil.encodeQuery(kb.keywordUrl + kb.getUriCode()), Namespaces.XLINK); keyword.addContent((Content) an.clone()); } catch (URIException e) { cs.setText(kb.getDefaultValue()); keyword.addContent((Content) cs.clone()); } } else { cs.setText(kb.getDefaultValue()); keyword.addContent((Content) cs.clone()); } keywords.add((Element) keyword.detach()); if (type == null) type = KeywordBean.createKeywordTypeElt(kb); if (thesaurusName == null) thesaurusName = KeywordBean.createThesaurusNameElt(kb); } // Add elements to the root MD_Keywords element. root.addContent(keywords); root.addContent(type); root.addContent(thesaurusName); return root; } /** * Creates keyword type element. * * @param kb * @return */ private static Element createKeywordTypeElt(KeywordBean kb) { Element type = new Element("type", Namespaces.GMD); Element keywordTypeCode = new Element("MD_KeywordTypeCode", Namespaces.GMD); keywordTypeCode.setAttribute("codeList", "http://www.isotc211.org/2005/resources/codeList.xml#MD_KeywordTypeCode"); keywordTypeCode.setAttribute("codeListValue", kb.getType()); type.addContent(keywordTypeCode); return type; } /** * Create an identifier/MD_Identifier that describes the thesaurus * * @return */ private static Element createIdentifier(String authority, String downloadUrl) { Element result = new Element("identifier", Namespaces.GMD); Element ident = new Element("MD_Identifier", Namespaces.GMD); Element code = new Element("code", Namespaces.GMD); Element gmxAnchor = new Element("Anchor", Namespaces.GMX).setText(authority); gmxAnchor.setAttribute("href", downloadUrl, Namespaces.XLINK); code.addContent(gmxAnchor); ident.addContent(code); result.addContent(ident); return result; } /** * Creates thesaurus name element. * * @param kb * @return */ private static Element createThesaurusNameElt(KeywordBean kb) { Element thesaurusName = new Element("thesaurusName", Namespaces.GMD); Element citation = new Element("CI_Citation", Namespaces.GMD); Element title = new Element("title", Namespaces.GMD); Element cs = new Element("CharacterString", Namespaces.GCO); Element date = new Element("date", Namespaces.GMD); cs.setText(kb.thesaurusTitle); if (StringUtils.hasLength(kb.thesaurusDate)) { Element ciDateEl = new Element("CI_Date", Namespaces.GMD); Element ciDateDateEl = new Element("date", Namespaces.GMD); Element ciDateDateGcoDateEl = new Element("Date", Namespaces.GCO); ciDateDateGcoDateEl.setText(kb.thesaurusDate); Element ciDateDatetypeEl = new Element("dateType", Namespaces.GMD); Element ciDateDatetypeCodeEl = new Element("CI_DateTypeCode", Namespaces.GMD); ciDateDatetypeCodeEl.setAttribute("codeList", "http://standards.iso.org/ittf/PubliclyAvailableStandards/ISO_19139_Schemas/resources/Codelist/ML_gmxCodelists.xml#CI_DateTypeCode"); ciDateDatetypeCodeEl.setAttribute("codeListValue", "publication"); ciDateDatetypeEl.addContent(ciDateDatetypeCodeEl); ciDateDateEl.addContent(ciDateDateGcoDateEl); ciDateEl.addContent(0, ciDateDateEl); ciDateEl.addContent(1, ciDateDatetypeEl); date.addContent(ciDateEl); } else { date.setAttribute("nilReason", "unknown", Namespaces.GCO); } title.addContent((Content) cs.clone()); Element id = createIdentifier("geonetwork.thesaurus." + kb.thesaurusKey, kb.downloadUrl); citation.addContent(0, title); citation.addContent(1, date); citation.addContent(2, id); thesaurusName.addContent(citation); return thesaurusName; } /** * Create a xml node for the current Keyword * * @return */ public Element toElement(String defaultLang, String... langs) { defaultLang = to3CharLang(defaultLang); List<String> prioritizedList = new ArrayList<String>(); prioritizedList.add(defaultLang); for (String s : langs) { s = to3CharLang(s); prioritizedList.add(s.toLowerCase()); } TreeSet<String> languages = new TreeSet<String>( new PrioritizedLangComparator(defaultLang, prioritizedList)); for (String l : values.keySet()) { l = to3CharLang(l); languages.add(l.toLowerCase()); } Element elKeyword = new Element("keyword"); Element elId = new Element("id"); elId.addContent(Integer.toString(this.getId())); Element elCode = new Element("code"); String code = this.getRelativeCode(); elCode.setText(code); // TODO : Add Thesaurus name Element elSelected = new Element("selected"); if (this.isSelected()) { elSelected.addContent("true"); } else { elSelected.addContent("false"); } elKeyword.addContent(elId); elKeyword.addContent(elCode); for (String language : languages) { if (!prioritizedList.isEmpty() && !prioritizedList.contains(language)) { continue; } Element elValue = new Element("value"); elValue.addContent(values.get(language)); elValue.setAttribute("lang", getIsoLanguageMapper().iso639_2_to_iso639_1(language, language.substring(2)).toUpperCase()); elKeyword.addContent(elValue); } Element elDefiniton = new Element("definition"); elDefiniton.addContent(getDefaultDefinition()); Element elUri = new Element("uri"); elUri.addContent(this.getUriCode()); String thesaurusType = this.getThesaurusKey(); thesaurusType = thesaurusType.replace('.', '-'); if (thesaurusType.contains("-")) thesaurusType = thesaurusType.split("-")[1]; elKeyword.setAttribute("type", thesaurusType); Element elthesaurus = new Element("thesaurus").setText(this.getThesaurusKey()); // Geo attribute if (this.getCoordEast() != null && this.getCoordWest() != null && this.getCoordSouth() != null && this.getCoordNorth() != null) { Element elBbox = new Element("geo"); Element elEast = new Element("east"); elEast.addContent(this.getCoordEast()); Element elWest = new Element("west"); elWest.addContent(this.getCoordWest()); Element elSouth = new Element("south"); elSouth.addContent(this.getCoordSouth()); Element elNorth = new Element("north"); elNorth.addContent(this.getCoordNorth()); elBbox.addContent(elEast); elBbox.addContent(elWest); elBbox.addContent(elSouth); elBbox.addContent(elNorth); elKeyword.addContent(elBbox); } elKeyword.addContent(elthesaurus); elKeyword.addContent(elDefiniton); elKeyword.addContent(elSelected); elKeyword.addContent(elUri); return elKeyword; } public String getDownloadUrl() { return downloadUrl; } public KeywordBean setDownloadUrl(String downloadUrl) { this.downloadUrl = downloadUrl; return this; } public void setIsoLanguageMapper(IsoLanguagesMapper isoLanguageMapper) { this.isoLanguageMapper = isoLanguageMapper; } private String to3CharLang(String lang) { return getIsoLanguageMapper().iso639_1_to_iso639_2(lang.toLowerCase(), lang.toLowerCase()); } public IsoLanguagesMapper getIsoLanguageMapper() { return isoLanguageMapper == null ? IsoLanguagesMapper.getInstance() : isoLanguageMapper; } /** * Set the namespace portion of the code * * @param namespace the new namespace * * @return this bean */ public KeywordBean setNamespaceCode(String namespace) { if (namespace.endsWith("#")) { this.code = namespace + getRelativeCode(); } else { this.code = namespace + "#" + getRelativeCode(); } return this; } /** * Set the id/relative portion of the code * * @param newCode the new relative code * * @return this bean */ public KeywordBean setRelativeCode(String newCode) { this.code = getNameSpaceCode() + newCode; return this; } /** * Remove the value with the provided language from this keyword * * @param lang language of value to remove * @return this */ public KeywordBean removeValue(String lang) { values.remove(lang); return this; } /** * Remove the definition with the provided language from this keyword * * @param lang language of definition to remove * @return this */ public KeywordBean removeDefinition(String lang) { definitions.remove(lang); return this; } public String getBroaderRelationship() { return broader; } public KeywordBean setBroaderRelationship(String broader) { this.broader = broader; return this; } @Override public String toString() { return getUriCode() + " : " + getDefaultValue(); } }