0001: //==============================================================================
0002: //===
0003: //=== DataManager
0004: //===
0005: //=============================================================================
0006: //=== Copyright (C) 2001-2007 Food and Agriculture Organization of the
0007: //=== United Nations (FAO-UN), United Nations World Food Programme (WFP)
0008: //=== and United Nations Environment Programme (UNEP)
0009: //===
0010: //=== This program is free software; you can redistribute it and/or modify
0011: //=== it under the terms of the GNU General Public License as published by
0012: //=== the Free Software Foundation; either version 2 of the License, or (at
0013: //=== your option) any later version.
0014: //===
0015: //=== This program is distributed in the hope that it will be useful, but
0016: //=== WITHOUT ANY WARRANTY; without even the implied warranty of
0017: //=== MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0018: //=== General Public License for more details.
0019: //===
0020: //=== You should have received a copy of the GNU General Public License
0021: //=== along with this program; if not, write to the Free Software
0022: //=== Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
0023: //===
0024: //=== Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2,
0025: //=== Rome - Italy. email: geonetwork@osgeo.org
0026: //==============================================================================
0027:
0028: package org.fao.geonet.kernel;
0029:
0030: import java.io.File;
0031: import java.util.Enumeration;
0032: import java.util.HashSet;
0033: import java.util.Hashtable;
0034: import java.util.Iterator;
0035: import java.util.List;
0036: import java.util.Set;
0037: import java.util.UUID;
0038: import java.util.Vector;
0039: import javax.xml.transform.Source;
0040: import javax.xml.transform.Result;
0041: import javax.xml.transform.Transformer;
0042: import javax.xml.transform.TransformerConfigurationException;
0043: import javax.xml.transform.TransformerException;
0044: import javax.xml.transform.TransformerFactory;
0045: import javax.xml.transform.dom.DOMSource;
0046: import javax.xml.transform.stream.StreamResult;
0047: import javax.xml.transform.stream.StreamSource;
0048: import jeeves.constants.Jeeves;
0049: import jeeves.resources.dbms.Dbms;
0050: import jeeves.server.UserSession;
0051: import jeeves.server.context.ServiceContext;
0052: import jeeves.utils.Log;
0053: import jeeves.utils.SerialFactory;
0054: import jeeves.utils.Xml;
0055: import org.fao.geonet.constants.Edit;
0056: import org.fao.geonet.constants.Geonet;
0057: import org.fao.geonet.kernel.harvest.HarvestManager;
0058: import org.fao.geonet.kernel.schema.MetadataSchema;
0059: import org.fao.geonet.kernel.search.SearchManager;
0060: import org.fao.geonet.kernel.setting.SettingManager;
0061: import org.fao.geonet.util.ISODate;
0062: import org.fao.geonet.util.FileCopyMgr;
0063: import org.jdom.Attribute;
0064: import org.jdom.Document;
0065: import org.jdom.Element;
0066: import org.jdom.JDOMException;
0067: import org.jdom.Namespace;
0068: import org.jdom.Text;
0069: import org.jdom.output.DOMOutputter;
0070:
0071: //=============================================================================
0072:
0073: /** Handles all operations on metadata (select,insert,update,delete etc...)
0074: */
0075:
0076: public class DataManager {
0077: //--------------------------------------------------------------------------
0078: //---
0079: //--- Constructor
0080: //---
0081: //--------------------------------------------------------------------------
0082:
0083: /** initializes the search manager and index not-indexed metadata
0084: */
0085:
0086: public DataManager(SearchManager sm, AccessManager am, Dbms dbms,
0087: SettingManager ss, String baseURL, String htmlCacheDir)
0088: throws Exception {
0089: searchMan = sm;
0090: accessMan = am;
0091: settingMan = ss;
0092:
0093: this .baseURL = baseURL;
0094: this .htmlCacheDir = htmlCacheDir;
0095:
0096: // get all metadata from DB
0097: Element result = dbms
0098: .select("SELECT id, changeDate FROM Metadata ORDER BY id ASC");
0099: List list = result.getChildren();
0100:
0101: Log.debug(Geonet.DATA_MANAGER, "DB CONTENT:\n'"
0102: + Xml.getString(result) + "'"); //DEBUG
0103:
0104: // get all metadata from index
0105: Hashtable docs = searchMan.getDocs();
0106:
0107: Log.debug(Geonet.DATA_MANAGER, "INDEX CONTENT:"); //DEBUG
0108:
0109: // index all metadata in DBMS if needed
0110: for (int i = 0; i < list.size(); i++) {
0111: // get metadata
0112: Element record = (Element) list.get(i);
0113: String id = record.getChildText("id");
0114:
0115: Log.debug(Geonet.DATA_MANAGER, "- record (" + id + ")"); //DEBUG
0116:
0117: Hashtable idxRec = (Hashtable) docs.get(id);
0118:
0119: // if metadata is not indexed index it
0120: if (idxRec == null)
0121: indexMetadata(dbms, id);
0122:
0123: // else, if indexed version is not the latest index it
0124: else {
0125: docs.remove(id);
0126:
0127: String lastChange = record.getChildText("changedate");
0128: String idxLastChange = (String) idxRec
0129: .get("_changeDate");
0130:
0131: Log.debug(Geonet.DATA_MANAGER, "- lastChange: "
0132: + lastChange); //DEBUG
0133: Log.debug(Geonet.DATA_MANAGER, "- idxLastChange: "
0134: + idxLastChange); //DEBUG
0135:
0136: if (!idxLastChange.equalsIgnoreCase(lastChange)) // date in index contains 't', date in DBMS contains 'T'
0137: indexMetadata(dbms, id);
0138: }
0139: }
0140:
0141: Log.debug(Geonet.DATA_MANAGER, "INDEX SURPLUS:"); //DEBUG
0142:
0143: // remove from index metadata not in DBMS
0144: for (Enumeration i = docs.keys(); i.hasMoreElements();) {
0145: String id = (String) i.nextElement();
0146: searchMan.delete("_id", id);
0147:
0148: Log.debug(Geonet.DATA_MANAGER, "- record (" + id + ")"); //DEBUG
0149: }
0150: }
0151:
0152: //--------------------------------------------------------------------------
0153:
0154: public void indexMetadata(Dbms dbms, String id) throws Exception {
0155:
0156: Log.debug(Geonet.DATA_MANAGER, "Indexing record (" + id + ")"); //DEBUG
0157:
0158: indexMetadata(dbms, id, searchMan);
0159: }
0160:
0161: //--------------------------------------------------------------------------
0162:
0163: public static void indexMetadata(Dbms dbms, String id,
0164: SearchManager sm) throws Exception {
0165: try {
0166: indexMetadataI(dbms, id, sm);
0167: } catch (JDOMException e) {
0168: Log.error(Geonet.DATA_MANAGER, "The metadata with id=" + id
0169: + " is corrupted");
0170: }
0171: }
0172:
0173: //--------------------------------------------------------------------------
0174:
0175: private static void indexMetadataI(Dbms dbms, String id,
0176: SearchManager sm) throws Exception {
0177: Vector moreFields = new Vector();
0178:
0179: // get metadata table fields
0180: Element md = XmlSerializer.select(dbms, "Metadata", id);
0181: String root = md.getName();
0182:
0183: String query = "SELECT schemaId, createDate, changeDate, source, isTemplate, title, uuid, "
0184: + "isHarvested, owner, groupOwner, popularity, rating FROM Metadata WHERE id = "
0185: + id;
0186:
0187: Element rec = dbms.select(query).getChild("record");
0188:
0189: String schema = rec.getChildText("schemaid");
0190: String createDate = rec.getChildText("createdate");
0191: String changeDate = rec.getChildText("changedate");
0192: String source = rec.getChildText("source");
0193: String isTemplate = rec.getChildText("istemplate");
0194: String title = rec.getChildText("title");
0195: String uuid = rec.getChildText("uuid");
0196: String isHarvested = rec.getChildText("isharvested");
0197: String owner = rec.getChildText("owner");
0198: String groupOwner = rec.getChildText("groupowner");
0199: String popularity = rec.getChildText("popularity");
0200: String rating = rec.getChildText("rating");
0201:
0202: Log
0203: .debug(Geonet.DATA_MANAGER, "record schema (" + schema
0204: + ")"); //DEBUG
0205: Log.debug(Geonet.DATA_MANAGER, "record createDate ("
0206: + createDate + ")"); //DEBUG
0207:
0208: moreFields.add(makeField("_root", root, true, true, false));
0209: moreFields.add(makeField("_schema", schema, true, true, false));
0210: moreFields.add(makeField("_createDate", createDate, true, true,
0211: false));
0212: moreFields.add(makeField("_changeDate", changeDate, true, true,
0213: false));
0214: moreFields.add(makeField("_source", source, true, true, false));
0215: moreFields.add(makeField("_isTemplate", isTemplate, true, true,
0216: false));
0217: moreFields.add(makeField("_title", title, true, true, false));
0218: moreFields.add(makeField("_uuid", uuid, true, true, false));
0219: moreFields.add(makeField("_isHarvested", isHarvested, true,
0220: true, false));
0221: moreFields.add(makeField("_owner", owner, true, true, false));
0222: moreFields.add(makeField("_dummy", "0", false, true, false));
0223: moreFields.add(makeField("_popularity", popularity, true, true,
0224: false));
0225: moreFields.add(makeField("_rating", rating, true, true, false));
0226:
0227: if (groupOwner != null)
0228: moreFields.add(makeField("_groupOwner", groupOwner, true,
0229: true, false));
0230:
0231: // get privileges
0232: List operations = dbms.select(
0233: "SELECT groupId, operationId FROM OperationAllowed "
0234: + "WHERE metadataId = " + id
0235: + " ORDER BY operationId ASC").getChildren();
0236:
0237: for (Iterator iter = operations.iterator(); iter.hasNext();) {
0238: Element operation = (Element) iter.next();
0239: String groupId = operation.getChildText("groupid");
0240: String operationId = operation.getChildText("operationid");
0241:
0242: moreFields.add(makeField("_op" + operationId, groupId,
0243: true, true, false));
0244: }
0245: // get categories
0246: List categories = dbms.select(
0247: "SELECT id, name FROM MetadataCateg, Categories "
0248: + "WHERE metadataId = " + id
0249: + " AND categoryId = id ORDER BY id")
0250: .getChildren();
0251:
0252: for (Iterator iter = categories.iterator(); iter.hasNext();) {
0253: Element category = (Element) iter.next();
0254: String categoryName = category.getChildText("name");
0255:
0256: moreFields.add(makeField("_cat", categoryName, true, true,
0257: false));
0258: }
0259:
0260: sm.index(schema, md, id, moreFields, isTemplate, title);
0261: }
0262:
0263: //--------------------------------------------------------------------------
0264:
0265: private static Element makeField(String name, String value,
0266: boolean store, boolean index, boolean token) {
0267: Element field = new Element("Field");
0268:
0269: field.setAttribute("name", name);
0270: field.setAttribute("string", value);
0271: field.setAttribute("store", store + "");
0272: field.setAttribute("index", index + "");
0273: field.setAttribute("token", token + "");
0274:
0275: return field;
0276: }
0277:
0278: //--------------------------------------------------------------------------
0279: //---
0280: //--- Schema management API
0281: //---
0282: //--------------------------------------------------------------------------
0283:
0284: public void setHarvestManager(HarvestManager hm) {
0285: harvestMan = hm;
0286: }
0287:
0288: //--------------------------------------------------------------------------
0289:
0290: public void addSchema(String id, String xmlSchemaFile,
0291: String xmlSuggestFile, String xmlSubstitutesFile)
0292: throws Exception {
0293: editLib.addSchema(id, xmlSchemaFile, xmlSuggestFile,
0294: xmlSubstitutesFile);
0295: }
0296:
0297: //--------------------------------------------------------------------------
0298:
0299: public MetadataSchema getSchema(String name) {
0300: return editLib.getSchema(name);
0301: }
0302:
0303: //--------------------------------------------------------------------------
0304:
0305: public Set<String> getSchemas() {
0306: return editLib.getSchemas();
0307: }
0308:
0309: //--------------------------------------------------------------------------
0310:
0311: public boolean existsSchema(String name) {
0312: return editLib.existsSchema(name);
0313: }
0314:
0315: //--------------------------------------------------------------------------
0316:
0317: public String getSchemaDir(String name) {
0318: return editLib.getSchemaDir(name);
0319: }
0320:
0321: //--------------------------------------------------------------------------
0322:
0323: public void validate(String schema, Element md) throws Exception {
0324: Xml.validate(editLib.getSchemaDir(schema) + Geonet.File.SCHEMA,
0325: md);
0326: }
0327:
0328: //--------------------------------------------------------------------------
0329:
0330: public Element schemaTron(String schemaPath, Element md, String id)
0331: throws Exception {
0332: String fileSchemaTronReport = doSchemaTronReport(schemaPath,
0333: md, id);
0334: return doSchemaTronForEditor(schemaPath, md);
0335: }
0336:
0337: //--------------------------------------------------------------------------
0338:
0339: public String doSchemaTronReport(String schemaPath, Element md,
0340: String id) throws Exception {
0341:
0342: String dirId = "SchematronReport" + id;
0343: String outDir = htmlCacheDir + File.separator + dirId;
0344: String inDir = htmlCacheDir + File.separator
0345: + "schematronscripts";
0346:
0347: // copy the schematron templates for the output report
0348: FileCopyMgr copier = new FileCopyMgr();
0349: copier.copyFiles(inDir, outDir);
0350:
0351: // convert the JDOM document to a DOM document
0352: Document mdDoc = new Document(md);
0353: DOMOutputter domOut = new DOMOutputter();
0354: org.w3c.dom.Document mdDomDoc = domOut.output(mdDoc);
0355:
0356: // set up the inputs to/output from the XSLT transformer and run it
0357: // xslt transformer
0358: String schemaTronReport = schemaPath + File.separator
0359: + Geonet.File.SCHEMATRON;
0360: StreamSource xsltSource = new StreamSource(new File(
0361: schemaTronReport));
0362:
0363: // output schematron-errors.html
0364: String fileOut = outDir + File.separator
0365: + "schematron-errors.html";
0366: File fileResult = new File(fileOut);
0367: Source source = new DOMSource(mdDomDoc);
0368:
0369: try {
0370: Transformer xformer = TransformerFactory.newInstance()
0371: .newTransformer(xsltSource);
0372: Result result = new StreamResult(fileResult.toURI()
0373: .getPath());
0374: xformer.transform(source, result);
0375: } catch (TransformerConfigurationException e) {
0376: System.out.println(e);
0377: } catch (TransformerException e) {
0378: System.out.println(e);
0379: }
0380:
0381: // now place anchors in the metadata xml so that schematron-report can
0382: // show the problems with the XML
0383:
0384: String schemaTronAnchors = schemaPath + File.separator
0385: + Geonet.File.SCHEMATRON_VERBID;
0386: StreamSource xsltAnchorSource = new StreamSource(new File(
0387: schemaTronAnchors));
0388: // output schematron-out.html
0389: String fileSchemaTronOut = outDir + File.separator
0390: + "schematron-out.html";
0391: File schemaTronOut = new File(fileSchemaTronOut);
0392: try {
0393: Transformer xformer = TransformerFactory.newInstance()
0394: .newTransformer(xsltAnchorSource);
0395: Result result = new StreamResult(schemaTronOut.toURI()
0396: .getPath());
0397: xformer.transform(source, result);
0398: } catch (TransformerConfigurationException e) {
0399: System.out.println(e);
0400: } catch (TransformerException e) {
0401: System.out.println(e);
0402: }
0403:
0404: return fileSchemaTronOut;
0405: }
0406:
0407: //--------------------------------------------------------------------------
0408:
0409: public Element doSchemaTronForEditor(String schemaPath, Element md)
0410: throws Exception {
0411:
0412: // enumerate the metadata xml so that we can report any problems found
0413: // by the schematron_xml script to the geonetwork editor
0414: editLib.enumerateTree(md);
0415:
0416: // get an xml version of the schematron errors and return for error display
0417: Element schemaTronXmlReport = getSchemaTronXmlReport(
0418: schemaPath, md);
0419:
0420: // remove editing info added by enumerateTree
0421: editLib.removeEditingInfo(md);
0422:
0423: return schemaTronXmlReport;
0424: }
0425:
0426: //--------------------------------------------------------------------------
0427:
0428: private Element getSchemaTronXmlReport(String schemaPath, Element md)
0429: throws Exception {
0430: // NOTE: this method assumes that you've run enumerateTree on the
0431: // metadata
0432: String schemaTronXmlXslt = schemaPath + File.separator
0433: + Geonet.File.SCHEMATRON_XML;
0434: Element schemaTronXmlOut = null;
0435:
0436: try {
0437: schemaTronXmlOut = Xml.transform(md, schemaTronXmlXslt);
0438: } catch (Exception e) {
0439: System.out.println(e);
0440: }
0441:
0442: return schemaTronXmlOut;
0443: }
0444:
0445: //--------------------------------------------------------------------------
0446:
0447: public AccessManager getAccessManager() {
0448: return accessMan;
0449: }
0450:
0451: //--------------------------------------------------------------------------
0452: //---
0453: //--- General purpose API
0454: //---
0455: //--------------------------------------------------------------------------
0456:
0457: public String extractUUID(String schema, Element md)
0458: throws Exception {
0459: String styleSheet = editLib.getSchemaDir(schema)
0460: + Geonet.File.EXTRACT_UUID;
0461: String uuid = Xml.transform(md, styleSheet).getText().trim();
0462:
0463: Log.debug(Geonet.DATA_MANAGER, "Extracted UUID '" + uuid
0464: + "' for schema '" + schema + "'");
0465:
0466: //--- needed to detach md from the document
0467: md.detach();
0468:
0469: return uuid;
0470: }
0471:
0472: //--------------------------------------------------------------------------
0473:
0474: public Element setUUID(String schema, String uuid, Element md)
0475: throws Exception {
0476: //--- setup environment
0477:
0478: Element env = new Element("env");
0479: env.addContent(new Element("uuid").setText(uuid));
0480:
0481: //--- setup root element
0482:
0483: Element root = new Element("root");
0484: root.addContent(md);
0485: root.addContent(env);
0486:
0487: //--- do an XSL transformation
0488:
0489: String styleSheet = editLib.getSchemaDir(schema)
0490: + Geonet.File.SET_UUID;
0491:
0492: return Xml.transform(root, styleSheet);
0493: }
0494:
0495: //--------------------------------------------------------------------------
0496:
0497: public String getMetadataId(Dbms dbms, String uuid)
0498: throws Exception {
0499: String query = "SELECT id FROM Metadata WHERE uuid=?";
0500:
0501: List list = dbms.select(query, uuid).getChildren();
0502:
0503: if (list.size() == 0)
0504: return null;
0505:
0506: Element record = (Element) list.get(0);
0507:
0508: return record.getChildText("id");
0509: }
0510:
0511: //--------------------------------------------------------------------------
0512:
0513: public String getMetadataId(ServiceContext srvContext, String uuid)
0514: throws Exception {
0515: Dbms dbms = (Dbms) srvContext.getResourceManager().open(
0516: Geonet.Res.MAIN_DB);
0517: String query = "SELECT id FROM Metadata WHERE uuid=?";
0518: List list = dbms.select(query, uuid).getChildren();
0519: if (list.size() == 0)
0520: return null;
0521: Element record = (Element) list.get(0);
0522: return record.getChildText("id");
0523: }
0524:
0525: //--------------------------------------------------------------------------
0526:
0527: public String getMetadataUuid(Dbms dbms, String id)
0528: throws Exception {
0529: String query = "SELECT uuid FROM Metadata WHERE id=?";
0530:
0531: List list = dbms.select(query, new Integer(id)).getChildren();
0532:
0533: if (list.size() == 0)
0534: return null;
0535:
0536: Element record = (Element) list.get(0);
0537:
0538: return record.getChildText("uuid");
0539: }
0540:
0541: //--------------------------------------------------------------------------
0542:
0543: public MdInfo getMetadataInfo(Dbms dbms, String id)
0544: throws Exception {
0545: String query = "SELECT id, uuid, schemaId, isTemplate, isHarvested, createDate, "
0546: + " changeDate, source, title, root, owner, groupOwner "
0547: + "FROM Metadata " + "WHERE id=?";
0548:
0549: List list = dbms.select(query, new Integer(id)).getChildren();
0550:
0551: if (list.size() == 0)
0552: return null;
0553:
0554: Element record = (Element) list.get(0);
0555:
0556: MdInfo info = new MdInfo();
0557:
0558: info.id = id;
0559: info.uuid = record.getChildText("uuid");
0560: info.schemaId = record.getChildText("schemaid");
0561: info.isHarvested = "y".equals(record
0562: .getChildText("isharvested"));
0563: info.createDate = record.getChildText("createdate");
0564: info.changeDate = record.getChildText("changedate");
0565: info.source = record.getChildText("source");
0566: info.title = record.getChildText("title");
0567: info.root = record.getChildText("root");
0568: info.owner = record.getChildText("owner");
0569: info.groupOwner = record.getChildText("groupowner");
0570:
0571: String temp = record.getChildText("istemplate");
0572:
0573: if ("y".equals(temp))
0574: info.template = MdInfo.Template.TEMPLATE;
0575:
0576: else if ("s".equals(temp))
0577: info.template = MdInfo.Template.SUBTEMPLATE;
0578:
0579: else
0580: info.template = MdInfo.Template.METADATA;
0581:
0582: return info;
0583: }
0584:
0585: //--------------------------------------------------------------------------
0586:
0587: public String getVersion(String id) {
0588: return editLib.getVersion(id);
0589: }
0590:
0591: //--------------------------------------------------------------------------
0592:
0593: public String getNewVersion(String id) {
0594: return editLib.getNewVersion(id);
0595: }
0596:
0597: //--------------------------------------------------------------------------
0598:
0599: public void setTemplate(Dbms dbms, int id, String isTemplate,
0600: String title) throws Exception {
0601: if (title == null)
0602: dbms.execute("UPDATE Metadata SET isTemplate=? WHERE id=?",
0603: isTemplate, id);
0604: else
0605: dbms
0606: .execute(
0607: "UPDATE Metadata SET isTemplate=?, title=? WHERE id=?",
0608: isTemplate, title, id);
0609: indexMetadata(dbms, Integer.toString(id));
0610: }
0611:
0612: //--------------------------------------------------------------------------
0613:
0614: public void setHarvested(Dbms dbms, int id, String harvestUuid)
0615: throws Exception {
0616: String value = (harvestUuid != null) ? "y" : "n";
0617: String query = "UPDATE Metadata SET isHarvested=?, harvestUuid=? WHERE id=?";
0618:
0619: dbms.execute(query, value, harvestUuid, id);
0620: indexMetadata(dbms, Integer.toString(id));
0621: }
0622:
0623: //--------------------------------------------------------------------------
0624:
0625: public void setHarvested(Dbms dbms, int id, String harvestUuid,
0626: String harvestUri) throws Exception {
0627: String value = (harvestUuid != null) ? "y" : "n";
0628: String query = "UPDATE Metadata SET isHarvested=?, harvestUuid=?, harvestUri=? WHERE id=?";
0629:
0630: dbms.execute(query, value, harvestUuid, harvestUri, id);
0631: indexMetadata(dbms, Integer.toString(id));
0632: }
0633:
0634: //---------------------------------------------------------------------------
0635:
0636: public String getSiteURL() {
0637: String host = settingMan.getValue("system/server/host");
0638: String port = settingMan.getValue("system/server/port");
0639: String locServ = baseURL + "/" + Jeeves.Prefix.SERVICE + "/en";
0640:
0641: return "http://" + host + (port == "80" ? "" : ":" + port)
0642: + locServ;
0643: }
0644:
0645: //--------------------------------------------------------------------------
0646:
0647: public String autodetectSchema(Element md) {
0648: Namespace nons = Namespace.NO_NAMESPACE;
0649: Namespace gmd = Namespace
0650: .getNamespace("http://www.isotc211.org/2005/gmd");
0651:
0652: Log.debug(Geonet.DATA_MANAGER, "Autodetect schema for: '"
0653: + md.getText() + "'");
0654:
0655: if (md.getName().equals("MD_Metadata")
0656: && md.getNamespace().equals(gmd))
0657: return "iso19139";
0658:
0659: if (md.getNamespace().equals(nons)) {
0660: if (md.getName().equals("Metadata"))
0661: return "iso19115";
0662:
0663: /* there are some other suggested container names,
0664: * like <dc>, <dublinCore>, <resource>, <record> and <metadata>
0665: * We may need to also check for those on import and export
0666: */
0667: if (md.getName().equals("simpledc"))
0668: return "dublin-core";
0669:
0670: if (md.getName().equals("metadata"))
0671: return "fgdc-std";
0672: }
0673:
0674: return null;
0675: }
0676:
0677: //--------------------------------------------------------------------------
0678:
0679: public void increasePopularity(Dbms dbms, String id)
0680: throws Exception {
0681: String query = "UPDATE Metadata SET popularity = popularity +1 WHERE "
0682: + "id = ? AND isHarvested='n'";
0683:
0684: dbms.execute(query, new Integer(id));
0685: indexMetadata(dbms, id);
0686: }
0687:
0688: //--------------------------------------------------------------------------
0689: /** Allow to rate a metadata
0690: * @param ipAddress IP address of the submitting client
0691: * @param rating range should be 1..5
0692: */
0693:
0694: public int rateMetadata(Dbms dbms, int id, String ipAddress,
0695: int rating) throws Exception {
0696: //--- first, update rating on the database
0697:
0698: String query = "UPDATE MetadataRating SET rating=? WHERE metadataId=? AND ipAddress=?";
0699:
0700: int res = dbms.execute(query, rating, id, ipAddress);
0701:
0702: if (res == 0) {
0703: query = "INSERT INTO MetadataRating(metadataId, ipAddress, rating) VALUES(?,?,?)";
0704: dbms.execute(query, id, ipAddress, rating);
0705: }
0706:
0707: //--- then, calculate new rating
0708:
0709: query = "SELECT sum(rating) as total FROM MetadataRating WHERE metadataId=?";
0710: List list = dbms.select(query, id).getChildren();
0711:
0712: String sum = ((Element) list.get(0)).getChildText("total");
0713:
0714: query = "SELECT count(*) as numr FROM MetadataRating WHERE metadataId=?";
0715: list = dbms.select(query, id).getChildren();
0716:
0717: String count = ((Element) list.get(0)).getChildText("numr");
0718:
0719: rating = (int) (Float.parseFloat(sum) / Float.parseFloat(count) + 0.5);
0720:
0721: Log.debug(Geonet.DATA_MANAGER, "Setting rating for id:" + id
0722: + " --> rating is:" + rating);
0723:
0724: //--- finally, update metadata and reindex it
0725:
0726: query = "UPDATE Metadata SET rating=? WHERE id=?";
0727: dbms.execute(query, rating, id);
0728: indexMetadata(dbms, Integer.toString(id));
0729:
0730: return rating;
0731: }
0732:
0733: //--------------------------------------------------------------------------
0734: //---
0735: //--- Metadata Insert API
0736: //---
0737: //--------------------------------------------------------------------------
0738:
0739: /** Create a new metadata duplicating an existing template
0740: */
0741:
0742: public String createMetadata(Dbms dbms, String templateId,
0743: String groupOwner, SerialFactory sf, String source,
0744: int owner) throws Exception {
0745: String query = "SELECT schemaId, data FROM Metadata WHERE id="
0746: + templateId;
0747:
0748: List listTempl = dbms.select(query).getChildren();
0749:
0750: if (listTempl.size() == 0)
0751: throw new IllegalArgumentException(
0752: "Template id not found : " + templateId);
0753:
0754: Element el = (Element) listTempl.get(0);
0755:
0756: String schema = el.getChildText("schemaid");
0757: String data = el.getChildText("data");
0758: String uuid = UUID.randomUUID().toString();
0759:
0760: //--- generate a new metadata id
0761: int serial = sf.getSerial(dbms, "Metadata");
0762:
0763: Element xml = updateFixedInfo(schema, Integer.toString(serial),
0764: Xml.loadString(data, false), uuid);
0765:
0766: //--- store metadata
0767:
0768: String id = XmlSerializer.insert(dbms, schema, xml, serial,
0769: source, uuid, owner, groupOwner);
0770:
0771: copyDefaultPrivForGroup(dbms, id, groupOwner);
0772:
0773: //--- store metadata categories copying them from the template
0774:
0775: List categList = dbms.select(
0776: "SELECT categoryId FROM MetadataCateg WHERE metadataId = "
0777: + templateId).getChildren();
0778:
0779: for (int i = 0; i < categList.size(); i++) {
0780: Element elRec = (Element) categList.get(i);
0781:
0782: String catId = elRec.getChildText("categoryid");
0783:
0784: setCategory(dbms, id, catId);
0785: }
0786:
0787: //--- index metadata and exit
0788:
0789: indexMetadata(dbms, id);
0790:
0791: return id;
0792: }
0793:
0794: //--------------------------------------------------------------------------
0795: /** Adds a metadata in xml form (the xml should be validated). This method is
0796: * used to add a metadata got from a remote site. Note that neighter permissions
0797: * nor lucene indexes are updated.
0798: */
0799:
0800: public String insertMetadataExt(Dbms dbms, String schema,
0801: Element md, SerialFactory sf, String source,
0802: String createDate, String changeDate, String uuid,
0803: int owner, String groupOwner) throws Exception {
0804: //--- generate a new metadata id
0805: int id = sf.getSerial(dbms, "Metadata");
0806:
0807: return insertMetadataExt(dbms, schema, md, id, source,
0808: createDate, changeDate, uuid, owner, groupOwner);
0809: }
0810:
0811: //--------------------------------------------------------------------------
0812: /** @param source the source of the metadata. If null, the local siteId will be used
0813: */
0814:
0815: public String insertMetadataExt(Dbms dbms, String schema,
0816: Element md, int id, String source, String createDate,
0817: String changeDate, String uuid, int owner, String groupOwner)
0818: throws Exception {
0819: if (source == null)
0820: source = getSiteID();
0821:
0822: //--- force namespace prefix for iso19139 metadata
0823: setNamespacePrefix(md);
0824:
0825: //--- Note: we cannot index metadata here. Indexing is done in the harvesting part
0826:
0827: return XmlSerializer.insert(dbms, schema, md, id, source, uuid,
0828: createDate, changeDate, "n", null, owner, groupOwner);
0829: }
0830:
0831: //--------------------------------------------------------------------------
0832: /** Adds a metadata in xml form (the xml should be validated). The group id is
0833: * used to setup permissions. Internal metadata fields are updated. Default
0834: * operations are set.
0835: */
0836:
0837: public String insertMetadata(Dbms dbms, String schema,
0838: String groupId, Element xml, SerialFactory sf,
0839: String source, String uuid, int owner) throws Exception {
0840: return insertMetadata(dbms, schema, groupId, xml, sf, source,
0841: uuid, "n", null, owner);
0842: }
0843:
0844: //--------------------------------------------------------------------------
0845:
0846: public String insertMetadata(Dbms dbms, String schema,
0847: String groupOwner, Element xml, SerialFactory sf,
0848: String source, String uuid, String isTemplate,
0849: String title, int owner) throws Exception {
0850: //--- generate a new metadata id
0851: int serial = sf.getSerial(dbms, "Metadata");
0852:
0853: if (isTemplate.equals("n"))
0854: xml = updateFixedInfo(schema, Integer.toString(serial),
0855: xml, uuid);
0856:
0857: //--- force namespace prefix for iso19139 metadata
0858: setNamespacePrefix(xml);
0859:
0860: //--- store metadata
0861:
0862: String id = XmlSerializer.insert(dbms, schema, xml, serial,
0863: source, uuid, isTemplate, title, owner, groupOwner);
0864:
0865: copyDefaultPrivForGroup(dbms, id, groupOwner);
0866: indexMetadata(dbms, id);
0867:
0868: return id;
0869: }
0870:
0871: //--------------------------------------------------------------------------
0872: //---
0873: //--- Metadata Get API
0874: //---
0875: //--------------------------------------------------------------------------
0876:
0877: /** Retrieves a metadata (in xml) given its id; adds editing information if needed
0878: */
0879:
0880: public Element getMetadata(ServiceContext srvContext, String id,
0881: boolean forEditing) throws Exception {
0882: Dbms dbms = (Dbms) srvContext.getResourceManager().open(
0883: Geonet.Res.MAIN_DB);
0884:
0885: Element md = XmlSerializer.select(dbms, "Metadata", id);
0886:
0887: if (md == null)
0888: return null;
0889:
0890: String version = null;
0891:
0892: if (forEditing) {
0893: String schema = getMetadataSchema(dbms, id);
0894: editLib.expandElements(schema, md);
0895: version = editLib.addEditingInfo(schema, id, md);
0896: Element elemChecks = getSchemaTronXmlReport(
0897: getSchemaDir(schema), md);
0898: if (elemChecks != null)
0899: md.addContent(elemChecks);
0900: }
0901:
0902: md.addNamespaceDeclaration(Edit.NAMESPACE);
0903:
0904: Element info = buildInfoElem(srvContext, id, version);
0905: md.addContent(info);
0906:
0907: md.detach();
0908: return md;
0909: }
0910:
0911: //--------------------------------------------------------------------------
0912: /** Retrieves a metadata element given it's ref
0913: */
0914:
0915: public Element getElementByRef(Element md, String ref) {
0916: return editLib.findElement(md, ref);
0917: }
0918:
0919: //--------------------------------------------------------------------------
0920: /** Returns true if the metadata exists in the database
0921: */
0922:
0923: public boolean existsMetadata(Dbms dbms, String id)
0924: throws Exception {
0925: //FIXME : should use lucene
0926:
0927: List list = dbms.select(
0928: "SELECT id FROM Metadata WHERE id=" + id).getChildren();
0929: return list.size() != 0;
0930: }
0931:
0932: //--------------------------------------------------------------------------
0933: /** Returns all the keywords in the system
0934: */
0935:
0936: public Element getKeywords() throws Exception {
0937: Vector keywords = searchMan.getTerms("keyword");
0938:
0939: Element el = new Element("keywords");
0940:
0941: for (int i = 0; i < keywords.size(); i++)
0942: el.addContent(new Element("keyword")
0943: .setText((String) keywords.get(i)));
0944:
0945: return el;
0946: }
0947:
0948: //--------------------------------------------------------------------------
0949: //---
0950: //--- Metadata Update API
0951: //---
0952: //--------------------------------------------------------------------------
0953:
0954: /** For Editing : adds an element to a metadata ([add] link)
0955: */
0956:
0957: public synchronized boolean addElement(Dbms dbms, String id,
0958: String ref, String name, String childName,
0959: String currVersion) throws Exception {
0960: Element md = XmlSerializer.select(dbms, "Metadata", id);
0961:
0962: //--- check if the metadata has been deleted
0963: if (md == null)
0964: return false;
0965:
0966: String schema = getMetadataSchema(dbms, id);
0967: editLib.expandElements(schema, md);
0968: editLib.enumerateTree(md);
0969:
0970: //--- check if the metadata has been modified from last time
0971: if (currVersion != null
0972: && !editLib.getVersion(id).equals(currVersion))
0973: return false;
0974:
0975: //--- get element to add
0976: Element el = editLib.findElement(md, ref);
0977:
0978: if (el == null)
0979: throw new IllegalStateException(
0980: "Element not found at ref = " + ref);
0981:
0982: //--- remove editing info added by previous call
0983:
0984: editLib.removeEditingInfo(md);
0985:
0986: if (childName.startsWith("_s")) {
0987: // add subtemplate
0988: String sid = childName.substring(2);
0989: Element subtemplate = XmlSerializer.select(dbms,
0990: "Metadata", sid);
0991: el.addContent(subtemplate);
0992: } else {
0993: // normal element
0994: Element child = editLib.addElement(schema, el, name);
0995: MetadataSchema mds = editLib.getSchema(schema);
0996: if (!childName.equals("")) {
0997: // or element
0998: String uChildName = editLib
0999: .getUnqualifiedName(childName);
1000: String prefix = editLib.getPrefix(childName);
1001: String ns = editLib.getNamespace(childName, md, mds);
1002: if (prefix.equals("")) {
1003: prefix = editLib.getPrefix(el.getName());
1004: ns = editLib.getNamespace(el.getName(), md, mds);
1005: }
1006: Element orChild = new Element(uChildName, prefix, ns);
1007: child.addContent(orChild);
1008:
1009: //--- add mandatory sub-tags
1010: editLib.fillElement(schema, child, orChild);
1011: }
1012: }
1013:
1014: editLib.contractElements(md);
1015: md = updateFixedInfo(schema, id, md, dbms);
1016: XmlSerializer.update(dbms, id, md);
1017:
1018: //--- update search criteria
1019: indexMetadata(dbms, id);
1020:
1021: return true;
1022: }
1023:
1024: //--------------------------------------------------------------------------
1025:
1026: public synchronized boolean addAttribute(Dbms dbms, String id,
1027: String ref, String name, String currVersion)
1028: throws Exception {
1029: Element md = XmlSerializer.select(dbms, "Metadata", id);
1030:
1031: //--- check if the metadata has been deleted
1032: if (md == null)
1033: return false;
1034:
1035: String schema = getMetadataSchema(dbms, id);
1036: editLib.expandElements(schema, md);
1037: editLib.enumerateTree(md);
1038:
1039: //--- check if the metadata has been modified from last time
1040: if (currVersion != null
1041: && !editLib.getVersion(id).equals(currVersion))
1042: return false;
1043:
1044: //--- get element to add
1045: Element el = editLib.findElement(md, ref);
1046:
1047: if (el == null)
1048: throw new IllegalStateException(
1049: "Element not found at ref = " + ref);
1050:
1051: //--- remove editing info added by previous call
1052: editLib.removeEditingInfo(md);
1053:
1054: el.setAttribute(new Attribute(name, ""));
1055:
1056: editLib.contractElements(md);
1057: md = updateFixedInfo(schema, id, md, dbms);
1058: XmlSerializer.update(dbms, id, md);
1059:
1060: //--- update search criteria
1061: indexMetadata(dbms, id);
1062:
1063: return true;
1064: }
1065:
1066: //--------------------------------------------------------------------------
1067: /** For Editing : removes an element from a metadata ([del] link)
1068: */
1069:
1070: public synchronized boolean deleteElement(Dbms dbms, String id,
1071: String ref, String currVersion) throws Exception {
1072: Element md = XmlSerializer.select(dbms, "Metadata", id);
1073:
1074: //--- check if the metadata has been deleted
1075: if (md == null)
1076: return false;
1077:
1078: String schema = getMetadataSchema(dbms, id);
1079: editLib.expandElements(schema, md);
1080: editLib.enumerateTree(md);
1081:
1082: //--- check if the metadata has been modified from last time
1083: if (currVersion != null
1084: && !editLib.getVersion(id).equals(currVersion))
1085: return false;
1086:
1087: //--- get element to remove
1088: Element el = editLib.findElement(md, ref);
1089:
1090: if (el == null)
1091: throw new IllegalStateException(
1092: "Element not found at ref = " + ref);
1093:
1094: el.detach();
1095:
1096: //--- remove editing info added by previous call
1097: editLib.removeEditingInfo(md);
1098:
1099: editLib.contractElements(md);
1100: md = updateFixedInfo(schema, id, md, dbms);
1101: XmlSerializer.update(dbms, id, md);
1102:
1103: //--- update search criteria
1104:
1105: indexMetadata(dbms, id);
1106:
1107: return true;
1108: }
1109:
1110: //--------------------------------------------------------------------------
1111: /** For Editing : removes an attribute from a metadata ([del] link)
1112: */
1113:
1114: public synchronized boolean deleteAttribute(Dbms dbms, String id,
1115: String ref, String name, String currVersion)
1116: throws Exception {
1117: Element md = XmlSerializer.select(dbms, "Metadata", id);
1118:
1119: //--- check if the metadata has been deleted
1120: if (md == null)
1121: return false;
1122:
1123: String schema = getMetadataSchema(dbms, id);
1124: editLib.expandElements(schema, md);
1125: editLib.enumerateTree(md);
1126:
1127: //--- check if the metadata has been modified from last time
1128: if (currVersion != null
1129: && !editLib.getVersion(id).equals(currVersion))
1130: return false;
1131:
1132: //--- get element to remove
1133: Element el = editLib.findElement(md, ref);
1134:
1135: if (el == null)
1136: throw new IllegalStateException(
1137: "Element not found at ref = " + ref);
1138:
1139: //--- remove editing info added by previous call
1140: editLib.removeEditingInfo(md);
1141:
1142: el.removeAttribute(name);
1143:
1144: editLib.contractElements(md);
1145: md = updateFixedInfo(schema, id, md, dbms);
1146: XmlSerializer.update(dbms, id, md);
1147:
1148: //--- update search criteria
1149: indexMetadata(dbms, id);
1150:
1151: return true;
1152: }
1153:
1154: //--------------------------------------------------------------------------
1155: /** For Editing : swap a tag with one of its sibling ([up] and [down] links)
1156: */
1157:
1158: public synchronized boolean swapElement(Dbms dbms, String id,
1159: String ref, String currVersion, boolean down)
1160: throws Exception {
1161: Element md = XmlSerializer.select(dbms, "Metadata", id);
1162:
1163: //--- check if the metadata has been deleted
1164:
1165: if (md == null)
1166: return false;
1167:
1168: String schema = getMetadataSchema(dbms, id);
1169: editLib.expandElements(schema, md);
1170: editLib.enumerateTree(md);
1171:
1172: //--- check if the metadata has been modified from last time
1173: if (currVersion != null
1174: && !editLib.getVersion(id).equals(currVersion))
1175: return false;
1176:
1177: //--- get element to swap
1178:
1179: Element elSwap = editLib.findElement(md, ref);
1180:
1181: if (elSwap == null)
1182: throw new IllegalStateException(
1183: "Element not found at ref = " + ref);
1184:
1185: //--- remove editing info added by previous call
1186: editLib.removeEditingInfo(md);
1187:
1188: //--------------------------------------------------------------------
1189: //--- swap elements
1190:
1191: int iSwapIndex = -1;
1192:
1193: List list = ((Element) elSwap.getParent()).getChildren(elSwap
1194: .getName(), elSwap.getNamespace());
1195:
1196: for (int i = 0; i < list.size(); i++)
1197: if (list.get(i) == elSwap) {
1198: iSwapIndex = i;
1199: break;
1200: }
1201:
1202: if (iSwapIndex == -1)
1203: throw new IllegalStateException(
1204: "Index not found for element --> " + elSwap);
1205:
1206: if (down)
1207: swapElements(elSwap, (Element) list.get(iSwapIndex + 1));
1208: else
1209: swapElements(elSwap, (Element) list.get(iSwapIndex - 1));
1210:
1211: editLib.contractElements(md);
1212: md = updateFixedInfo(schema, id, md, dbms);
1213: XmlSerializer.update(dbms, id, md);
1214:
1215: return true;
1216: }
1217:
1218: //--------------------------------------------------------------------------
1219: /** For Editing : updates all leaves with new values
1220: */
1221:
1222: public synchronized boolean updateMetadata(UserSession session,
1223: Dbms dbms, String id, String currVersion,
1224: Hashtable changes, boolean validate) throws Exception {
1225: Element md = XmlSerializer.select(dbms, "Metadata", id);
1226:
1227: //--- check if the metadata has been deleted
1228: if (md == null)
1229: return false;
1230: String schema = getMetadataSchema(dbms, id);
1231: editLib.expandElements(schema, md);
1232: editLib.enumerateTree(md);
1233:
1234: //--- check if the metadata has been modified from last time
1235: if (currVersion != null
1236: && !editLib.getVersion(id).equals(currVersion))
1237: return false;
1238:
1239: //--------------------------------------------------------------------
1240: //--- update elements
1241:
1242: for (Enumeration e = changes.keys(); e.hasMoreElements();) {
1243: String ref = ((String) e.nextElement()).trim();
1244: String val = ((String) changes.get(ref)).trim();
1245: String attr = null;
1246:
1247: int at = ref.indexOf("_");
1248: if (at != -1) {
1249: attr = ref.substring(at + 1);
1250: ref = ref.substring(0, at);
1251: }
1252: Element el = editLib.findElement(md, ref);
1253: if (el == null)
1254: throw new IllegalStateException(
1255: "Element not found at ref = " + ref);
1256:
1257: if (attr != null) {
1258: // The following work-around decodes any attribute name that has a COLON in it
1259: // The : is replaced by the word COLON in the xslt so that it can be processed
1260: // by the XML Serializer when an update is submitted - a better solution is
1261: // required based on the form being submitted as an XML tree as opposed to name
1262: // value pairs (XFORMS is being investigated)
1263: Integer indexColon = attr.indexOf("COLON");
1264: if (indexColon != -1) {
1265: String prefix = attr.substring(0, indexColon);
1266: String localname = attr.substring(indexColon + 5);
1267: String namespace = editLib.getNamespace(prefix
1268: + ":" + localname, md, getSchema(schema));
1269: Namespace attrNS = Namespace.getNamespace(prefix,
1270: namespace);
1271: if (el.getAttribute(localname, attrNS) != null) {
1272: el.setAttribute(new Attribute(localname, val,
1273: attrNS));
1274: }
1275: // End of work-around
1276: } else {
1277: if (el.getAttribute(attr) != null)
1278: el.setAttribute(new Attribute(attr, val));
1279: }
1280: } else {
1281: List content = el.getContent();
1282:
1283: for (int i = 0; i < content.size(); i++) {
1284: if (content.get(i) instanceof Text) {
1285: el.removeContent((Text) content.get(i));
1286: i--;
1287: }
1288: }
1289: el.addContent(val);
1290: }
1291: }
1292: //--- remove editing info added by previous call
1293: editLib.removeEditingInfo(md);
1294:
1295: return updateMetadata(session, dbms, id, md, validate,
1296: currVersion);
1297: }
1298:
1299: //--------------------------------------------------------------------------
1300:
1301: public synchronized boolean updateMetadata(UserSession session,
1302: Dbms dbms, String id, Element md, boolean validate,
1303: String version) throws Exception {
1304: //--- check if the metadata has been modified from last time
1305: if (version != null && !editLib.getVersion(id).equals(version))
1306: return false;
1307:
1308: editLib.contractElements(md);
1309: String schema = getMetadataSchema(dbms, id);
1310: md = updateFixedInfo(schema, id, md, dbms);
1311:
1312: if (validate) {
1313: validate(schema, md);
1314: Element schemaTronXml = schemaTron(getSchemaDir(schema),
1315: md, id);
1316: session.setProperty("schematron_" + id, schemaTronXml);
1317: }
1318:
1319: XmlSerializer.update(dbms, id, md);
1320:
1321: //--- update search criteria
1322: indexMetadata(dbms, id);
1323:
1324: return true;
1325: }
1326:
1327: //--------------------------------------------------------------------------
1328: //--- Used by the harvesting procedure
1329:
1330: public void updateMetadataExt(Dbms dbms, String id, Element md,
1331: String changeDate) throws Exception {
1332: XmlSerializer.update(dbms, id, md, changeDate);
1333: }
1334:
1335: //--------------------------------------------------------------------------
1336: //---
1337: //--- Metadata Delete API
1338: //---
1339: //--------------------------------------------------------------------------
1340:
1341: /** Removes a metadata
1342: */
1343:
1344: public synchronized void deleteMetadata(Dbms dbms, String id)
1345: throws Exception {
1346: //--- remove operations
1347: deleteMetadataOper(dbms, id, false);
1348:
1349: //--- remove categories
1350: deleteAllMetadataCateg(dbms, id);
1351:
1352: dbms.execute("DELETE FROM MetadataRating WHERE metadataId=?",
1353: new Integer(id));
1354:
1355: //--- remove metadata
1356: XmlSerializer.delete(dbms, "Metadata", id);
1357:
1358: //--- update search criteria
1359: searchMan.delete("_id", id + "");
1360: }
1361:
1362: //--------------------------------------------------------------------------
1363: /** Remove all operations stored for a metadata
1364: */
1365:
1366: public void deleteMetadataOper(Dbms dbms, String id,
1367: boolean skipAllIntranet) throws Exception {
1368: String query = "DELETE FROM OperationAllowed WHERE metadataId="
1369: + id;
1370:
1371: if (skipAllIntranet)
1372: query += " AND groupId>1";
1373:
1374: dbms.execute(query);
1375: }
1376:
1377: //--------------------------------------------------------------------------
1378: /** Remove all categories stored for a metadata
1379: */
1380:
1381: public void deleteAllMetadataCateg(Dbms dbms, String id)
1382: throws Exception {
1383: String query = "DELETE FROM MetadataCateg WHERE metadataId="
1384: + id;
1385:
1386: dbms.execute(query);
1387: }
1388:
1389: //--------------------------------------------------------------------------
1390: //---
1391: //--- Metadata thumbnail API
1392: //---
1393: //--------------------------------------------------------------------------
1394:
1395: public Element getThumbnails(Dbms dbms, String id) throws Exception {
1396: Element md = XmlSerializer.select(dbms, "Metadata", id);
1397:
1398: if (md == null)
1399: return null;
1400:
1401: md.detach();
1402:
1403: String schema = getMetadataSchema(dbms, id);
1404:
1405: //--- do an XSL transformation
1406:
1407: String styleSheet = editLib.getSchemaDir(schema)
1408: + Geonet.File.EXTRACT_THUMBNAILS;
1409:
1410: Element result = Xml.transform(md, styleSheet);
1411: result.addContent(new Element("id").setText(id));
1412:
1413: return result;
1414: }
1415:
1416: //--------------------------------------------------------------------------
1417:
1418: public void setThumbnail(Dbms dbms, String id, boolean small,
1419: String file) throws Exception {
1420: int pos = file.lastIndexOf(".");
1421: String ext = (pos == -1) ? "???" : file.substring(pos + 1);
1422:
1423: Element env = new Element("env");
1424: env.addContent(new Element("file").setText(file));
1425: env.addContent(new Element("ext").setText(ext));
1426:
1427: manageThumbnail(dbms, id, small, env, Geonet.File.SET_THUMBNAIL);
1428: }
1429:
1430: //--------------------------------------------------------------------------
1431:
1432: public void unsetThumbnail(Dbms dbms, String id, boolean small)
1433: throws Exception {
1434: Element env = new Element("env");
1435:
1436: manageThumbnail(dbms, id, small, env,
1437: Geonet.File.UNSET_THUMBNAIL);
1438: }
1439:
1440: //--------------------------------------------------------------------------
1441:
1442: private void manageThumbnail(Dbms dbms, String id, boolean small,
1443: Element env, String styleSheet) throws Exception {
1444: Element md = XmlSerializer.select(dbms, "Metadata", id);
1445:
1446: if (md == null)
1447: return;
1448:
1449: md.detach();
1450:
1451: String schema = getMetadataSchema(dbms, id);
1452:
1453: //-----------------------------------------------------------------------
1454: //--- remove thumbnail from metadata
1455:
1456: //--- setup environment
1457:
1458: String type = small ? "thumbnail" : "large_thumbnail";
1459:
1460: env.addContent(new Element("type").setText(type));
1461:
1462: //--- setup root element
1463:
1464: Element root = new Element("root");
1465: root.addContent(md);
1466: root.addContent(env);
1467:
1468: //--- do an XSL transformation
1469:
1470: styleSheet = editLib.getSchemaDir(schema) + styleSheet;
1471:
1472: md = Xml.transform(root, styleSheet);
1473: XmlSerializer.update(dbms, id, md);
1474:
1475: //--- update search criteria
1476: indexMetadata(dbms, id);
1477: }
1478:
1479: //--------------------------------------------------------------------------
1480: //---
1481: //--- Privileges API
1482: //---
1483: //--------------------------------------------------------------------------
1484:
1485: /** Adds a permission to a group. Metadata is not reindexed
1486: */
1487:
1488: public void setOperation(Dbms dbms, String mdId, String grpId,
1489: String opId) throws Exception {
1490: Object args[] = { new Integer(mdId), new Integer(grpId),
1491: new Integer(opId) };
1492:
1493: String query = "SELECT metadataId FROM OperationAllowed "
1494: + "WHERE metadataId=? AND groupId=? AND operationId=?";
1495:
1496: Element elRes = dbms.select(query, args);
1497:
1498: if (elRes.getChildren().size() == 0)
1499: dbms.execute(
1500: "INSERT INTO OperationAllowed(metadataId, groupId, operationId) "
1501: + "VALUES(?,?,?)", args);
1502: }
1503:
1504: //--------------------------------------------------------------------------
1505:
1506: public void unsetOperation(Dbms dbms, int mdId, int groupId,
1507: int operId) throws Exception {
1508: String query = "DELETE FROM OperationAllowed "
1509: + "WHERE metadataId=? AND groupId=? AND operationId=?";
1510:
1511: dbms.execute(query, mdId, groupId, operId);
1512: }
1513:
1514: //--------------------------------------------------------------------------
1515: //---
1516: //--- Categories API
1517: //---
1518: //--------------------------------------------------------------------------
1519:
1520: /** Adds a category to a metadata. Metadata is not reindexed
1521: */
1522:
1523: public void setCategory(Dbms dbms, String mdId, String categId)
1524: throws Exception {
1525: Object args[] = { new Integer(mdId), new Integer(categId) };
1526:
1527: if (!isCategorySet(dbms, mdId, categId))
1528: dbms
1529: .execute(
1530: "INSERT INTO MetadataCateg(metadataId, categoryId) VALUES(?,?)",
1531: args);
1532: }
1533:
1534: //--------------------------------------------------------------------------
1535:
1536: public boolean isCategorySet(Dbms dbms, String mdId, String categId)
1537: throws Exception {
1538: String query = "SELECT metadataId FROM MetadataCateg "
1539: + "WHERE metadataId=? AND categoryId=?";
1540:
1541: Element elRes = dbms.select(query, new Integer(mdId),
1542: new Integer(categId));
1543:
1544: return (elRes.getChildren().size() != 0);
1545: }
1546:
1547: //--------------------------------------------------------------------------
1548:
1549: public void unsetCategory(Dbms dbms, String mdId, String categId)
1550: throws Exception {
1551: String query = "DELETE FROM MetadataCateg WHERE metadataId=? AND categoryId=?";
1552:
1553: dbms.execute(query, new Integer(mdId), new Integer(categId));
1554: }
1555:
1556: //--------------------------------------------------------------------------
1557:
1558: public Element getCategories(Dbms dbms, String mdId)
1559: throws Exception {
1560: String query = "SELECT id, name FROM Categories, MetadataCateg "
1561: + "WHERE id=categoryId AND metadataId=?";
1562:
1563: return dbms.select(query, new Integer(mdId));
1564: }
1565:
1566: //--------------------------------------------------------------------------
1567: //---
1568: //--- Private methods
1569: //---
1570: //--------------------------------------------------------------------------
1571:
1572: /** Used for editing : swaps children of 2 tags
1573: */
1574:
1575: private void swapElements(Element el1, Element el2) {
1576: if (el1.getChildren().size() != 0) {
1577: Vector v1 = collectElements(el1);
1578: Vector v2 = collectElements(el2);
1579:
1580: addElements(el1, v2);
1581: addElements(el2, v1);
1582: } else {
1583: //--- swap text
1584:
1585: String sValue1 = el1.getText();
1586: String sValue2 = el2.getText();
1587:
1588: el1.setText(sValue2);
1589: el2.setText(sValue1);
1590: }
1591: }
1592:
1593: //--------------------------------------------------------------------------
1594: /** Collects all children of a tag, removing them from the parent
1595: */
1596:
1597: private Vector collectElements(Element el) {
1598: Vector v = new Vector();
1599:
1600: List list = el.getChildren();
1601:
1602: for (int i = 0; i < list.size(); i++)
1603: v.add(list.get(i));
1604:
1605: el.removeContent();
1606:
1607: return v;
1608: }
1609:
1610: //--------------------------------------------------------------------------
1611: /** Add all tags in a vector to a tag
1612: */
1613:
1614: private void addElements(Element el, Vector v) {
1615: for (int i = 0; i < v.size(); i++)
1616: el.addContent((Element) v.get(i));
1617: }
1618:
1619: //--------------------------------------------------------------------------
1620:
1621: private Element updateFixedInfo(String schema, String id,
1622: Element md, Dbms dbms) throws Exception {
1623: String query = "SELECT uuid, source, isTemplate FROM Metadata WHERE id = "
1624: + id;
1625:
1626: Element rec = dbms.select(query).getChild("record");
1627: String isTemplate = rec.getChildText("istemplate");
1628:
1629: // don't process templates
1630: if (isTemplate.equals("n")) {
1631: String uuid = rec.getChildText("uuid");
1632:
1633: return updateFixedInfo(schema, id, md, uuid);
1634: } else
1635: return md;
1636: }
1637:
1638: //--------------------------------------------------------------------------
1639:
1640: public Element updateFixedInfo(String schema, String id,
1641: Element md, String uuid) throws Exception {
1642: //--- setup environment
1643:
1644: Element env = new Element("env");
1645:
1646: env.addContent(new Element("id").setText(id));
1647: env.addContent(new Element("uuid").setText(uuid));
1648: env.addContent(new Element("changeDate").setText(new ISODate()
1649: .toString()));
1650: env.addContent(new Element("siteURL").setText(getSiteURL()));
1651:
1652: //--- setup root element
1653:
1654: Element root = new Element("root");
1655: root.addContent(md);
1656: root.addContent(env);
1657:
1658: //--- do an XSL transformation
1659:
1660: String styleSheet = editLib.getSchemaDir(schema)
1661: + Geonet.File.UPDATE_FIXED_INFO;
1662:
1663: return Xml.transform(root, styleSheet);
1664: }
1665:
1666: //--------------------------------------------------------------------------
1667:
1668: private Element buildInfoElem(ServiceContext context, String id,
1669: String version) throws Exception {
1670: Dbms dbms = (Dbms) context.getResourceManager().open(
1671: Geonet.Res.MAIN_DB);
1672:
1673: String query = "SELECT schemaId, createDate, changeDate, source, isTemplate, title, "
1674: + "uuid, isHarvested, harvestUuid, popularity, rating FROM Metadata WHERE id = "
1675: + id;
1676:
1677: // add Metadata table infos: schemaId, createDate, changeDate, source,
1678: Element rec = dbms.select(query).getChild("record");
1679:
1680: String schema = rec.getChildText("schemaid");
1681: String createDate = rec.getChildText("createdate");
1682: String changeDate = rec.getChildText("changedate");
1683: String source = rec.getChildText("source");
1684: String isTemplate = rec.getChildText("istemplate");
1685: String title = rec.getChildText("title");
1686: String uuid = rec.getChildText("uuid");
1687: String isHarvested = rec.getChildText("isharvested");
1688: String harvestUuid = rec.getChildText("harvestuuid");
1689: String popularity = rec.getChildText("popularity");
1690: String rating = rec.getChildText("rating");
1691:
1692: Element info = new Element(Edit.RootChild.INFO, Edit.NAMESPACE);
1693:
1694: addElement(info, Edit.Info.Elem.ID, id);
1695: addElement(info, Edit.Info.Elem.SCHEMA, schema);
1696: addElement(info, Edit.Info.Elem.CREATE_DATE, createDate);
1697: addElement(info, Edit.Info.Elem.CHANGE_DATE, changeDate);
1698: addElement(info, Edit.Info.Elem.IS_TEMPLATE, isTemplate);
1699: addElement(info, Edit.Info.Elem.TITLE, title);
1700: addElement(info, Edit.Info.Elem.SOURCE, source);
1701: addElement(info, Edit.Info.Elem.UUID, uuid);
1702: addElement(info, Edit.Info.Elem.IS_HARVESTED, isHarvested);
1703: addElement(info, Edit.Info.Elem.POPULARITY, popularity);
1704: addElement(info, Edit.Info.Elem.RATING, rating);
1705:
1706: if (isHarvested.equals("y"))
1707: info.addContent(harvestMan.getHarvestInfo(harvestUuid, id,
1708: uuid));
1709:
1710: if (version != null)
1711: addElement(info, Edit.Info.Elem.VERSION, version);
1712:
1713: // add operations
1714: HashSet hsOper = accessMan.getOperations(context, id, context
1715: .getIpAddress());
1716:
1717: addElement(info, Edit.Info.Elem.VIEW, String.valueOf(hsOper
1718: .contains(AccessManager.OPER_VIEW)));
1719: addElement(info, Edit.Info.Elem.NOTIFY, String.valueOf(hsOper
1720: .contains(AccessManager.OPER_NOTIFY)));
1721: addElement(info, Edit.Info.Elem.DOWNLOAD, String.valueOf(hsOper
1722: .contains(AccessManager.OPER_DOWNLOAD)));
1723: addElement(info, Edit.Info.Elem.DYNAMIC, String.valueOf(hsOper
1724: .contains(AccessManager.OPER_DYNAMIC)));
1725: addElement(info, Edit.Info.Elem.FEATURED, String.valueOf(hsOper
1726: .contains(AccessManager.OPER_FEATURED)));
1727:
1728: if (accessMan.canEdit(context, id))
1729: addElement(info, Edit.Info.Elem.EDIT, "true");
1730:
1731: // add categories
1732: List categories = dbms.select(
1733: "SELECT id, name FROM MetadataCateg, Categories "
1734: + "WHERE metadataId = " + id
1735: + " AND categoryId = id ORDER BY id")
1736: .getChildren();
1737:
1738: for (Iterator iter = categories.iterator(); iter.hasNext();) {
1739: Element category = (Element) iter.next();
1740: addElement(info, Edit.Info.Elem.CATEGORY, category
1741: .getChildText("name"));
1742: }
1743:
1744: return info;
1745: }
1746:
1747: //--------------------------------------------------------------------------
1748:
1749: private static void addElement(Element root, String name,
1750: String value) {
1751: root.addContent(new Element(name).setText(value));
1752: }
1753:
1754: //--------------------------------------------------------------------------
1755:
1756: private String getMetadataSchema(Dbms dbms, String id)
1757: throws Exception {
1758: List list = dbms.select(
1759: "SELECT schemaId FROM Metadata WHERE id = " + id)
1760: .getChildren();
1761:
1762: if (list.size() == 0)
1763: throw new IllegalArgumentException(
1764: "Metadata not found for id : " + id);
1765: else {
1766: // get metadata
1767: Element record = (Element) list.get(0);
1768: return record.getChildText("schemaid");
1769: }
1770: }
1771:
1772: //--------------------------------------------------------------------------
1773:
1774: private void copyDefaultPrivForGroup(Dbms dbms, String id,
1775: String groupId) throws Exception {
1776: //--- store access operations for group
1777:
1778: setOperation(dbms, id, groupId, AccessManager.OPER_VIEW);
1779: setOperation(dbms, id, groupId, AccessManager.OPER_DOWNLOAD);
1780: setOperation(dbms, id, groupId, AccessManager.OPER_NOTIFY);
1781: setOperation(dbms, id, groupId, AccessManager.OPER_DYNAMIC);
1782: }
1783:
1784: //--------------------------------------------------------------------------
1785:
1786: private String getSiteID() {
1787: return settingMan.getValue("system/site/siteId");
1788: }
1789:
1790: //---------------------------------------------------------------------------
1791: //---
1792: //--- Static methods
1793: //---
1794: //---------------------------------------------------------------------------
1795:
1796: public static void setNamespacePrefix(Element md) {
1797: //--- if the metadata has no namespace or already has a namespace then
1798: //--- we must skip this phase
1799:
1800: Namespace ns = md.getNamespace();
1801: // System.out.println("DM: Namespace prefix is '"+md.getNamespacePrefix()+"'"); // DEBUG
1802: if (ns == Namespace.NO_NAMESPACE
1803: || (!md.getNamespacePrefix().equals("")))
1804: return;
1805:
1806: //--- set prefix for iso19139 metadata
1807:
1808: ns = Namespace.getNamespace("gmd", md.getNamespace().getURI());
1809: setNamespacePrefix(md, ns);
1810: }
1811:
1812: //---------------------------------------------------------------------------
1813:
1814: private static void setNamespacePrefix(Element md, Namespace ns) {
1815: if (md.getNamespaceURI().equals(ns.getURI()))
1816: md.setNamespace(ns);
1817:
1818: for (Object o : md.getChildren())
1819: setNamespacePrefix((Element) o, ns);
1820: }
1821:
1822: //--------------------------------------------------------------------------
1823: //---
1824: //--- Variables
1825: //---
1826: //--------------------------------------------------------------------------
1827:
1828: private String baseURL;
1829:
1830: private EditLib editLib = new EditLib(this );
1831:
1832: private AccessManager accessMan;
1833: private SearchManager searchMan;
1834: private SettingManager settingMan;
1835: private HarvestManager harvestMan;
1836: private String htmlCacheDir;
1837: }
1838:
1839: //=============================================================================
|