Java tutorial
/* * Copyright (C) 2001-2016 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * * Contact: Jeroen Ticheler - FAO - Viale delle Terme di Caracalla 2, * Rome - Italy. email: geonetwork@osgeo.org */ package org.fao.geonet.api.records.editing; import io.swagger.annotations.*; import jeeves.server.UserSession; import jeeves.server.dispatchers.guiservices.XmlFile; import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang.StringUtils; import org.fao.geonet.ApplicationContextHolder; import org.fao.geonet.api.API; import org.fao.geonet.api.ApiParams; import org.fao.geonet.api.ApiUtils; import org.fao.geonet.api.records.model.Direction; import org.fao.geonet.api.tools.i18n.LanguageUtils; import org.fao.geonet.constants.Geonet; import org.fao.geonet.constants.Params; import org.fao.geonet.domain.AbstractMetadata; import org.fao.geonet.domain.MetadataType; import org.fao.geonet.domain.ReservedGroup; import org.fao.geonet.domain.ReservedOperation; import org.fao.geonet.events.history.RecordUpdatedEvent; import org.fao.geonet.kernel.*; import org.fao.geonet.kernel.datamanager.IMetadataValidator; import org.fao.geonet.kernel.metadata.StatusActions; import org.fao.geonet.kernel.metadata.StatusActionsFactory; import org.fao.geonet.kernel.setting.SettingManager; import org.fao.geonet.repository.MetadataValidationRepository; import org.fao.geonet.repository.OperationAllowedRepository; import org.fao.geonet.repository.specification.MetadataValidationSpecs; import org.fao.geonet.utils.Xml; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; import org.jdom.output.XMLOutputter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import java.io.IOException; import java.nio.file.Path; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import jeeves.server.context.ServiceContext; import jeeves.services.ReadWriteController; import springfox.documentation.annotations.ApiIgnore; import static jeeves.guiservices.session.Get.getSessionAsXML; import static org.fao.geonet.api.ApiParams.API_CLASS_RECORD_OPS; import static org.fao.geonet.api.ApiParams.API_CLASS_RECORD_TAG; import static org.fao.geonet.api.ApiParams.API_PARAM_RECORD_UUID; import static org.fao.geonet.repository.specification.OperationAllowedSpecs.hasGroupId; import static org.fao.geonet.repository.specification.OperationAllowedSpecs.hasMetadataId; import static org.fao.geonet.repository.specification.OperationAllowedSpecs.hasOperation; import static org.springframework.data.jpa.domain.Specifications.where; @RequestMapping(value = { "/api/records", "/api/" + API.VERSION_0_1 + "/records" }) @Api(value = API_CLASS_RECORD_TAG, tags = API_CLASS_RECORD_TAG, description = API_CLASS_RECORD_OPS) @Controller("recordEditing") @PreAuthorize("hasRole('Editor')") @ReadWriteController public class MetadataEditingApi { @Autowired LanguageUtils languageUtils; @ApiOperation(value = "Edit a record", notes = "Return HTML form for editing.", nickname = "editor") @RequestMapping(value = "/{metadataUuid}/editor", method = RequestMethod.GET, consumes = { MediaType.ALL_VALUE }, produces = { MediaType.APPLICATION_XML_VALUE }) @PreAuthorize("hasRole('Editor')") @ResponseStatus(HttpStatus.OK) @ApiResponses(value = { @ApiResponse(code = 200, message = "The editor form."), @ApiResponse(code = 403, message = ApiParams.API_RESPONSE_NOT_ALLOWED_CAN_EDIT) }) @ResponseBody public Element startEditing( @ApiParam(value = API_PARAM_RECORD_UUID, required = true) @PathVariable String metadataUuid, @ApiParam(value = "Tab") @RequestParam(defaultValue = "simple") String currTab, @RequestParam(defaultValue = "false") boolean withAttributes, @ApiIgnore @ApiParam(hidden = true) HttpSession session, @ApiIgnore @ApiParam(hidden = true) @RequestParam Map<String, String> allRequestParams, HttpServletRequest request) throws Exception { AbstractMetadata metadata = ApiUtils.canEditRecord(metadataUuid, request); boolean showValidationErrors = false; boolean starteditingsession = true; ServiceContext context = ApiUtils.createServiceContext(request); ApplicationContext applicationContext = ApplicationContextHolder.get(); if (starteditingsession) { DataManager dm = applicationContext.getBean(DataManager.class); dm.startEditingSession(context, String.valueOf(metadata.getId())); } Element elMd = new AjaxEditUtils(context).getMetadataEmbedded(context, String.valueOf(metadata.getId()), true, showValidationErrors); return buildEditorForm(currTab, session, allRequestParams, request, metadata.getId(), elMd, metadata.getDataInfo().getSchemaId(), showValidationErrors, context, applicationContext, false, false); } @ApiOperation(value = "Save edits", notes = "Save the HTML form content.", nickname = "saveEdits") @RequestMapping(value = "/{metadataUuid}/editor", method = RequestMethod.POST, consumes = { MediaType.ALL_VALUE }, produces = { MediaType.APPLICATION_XML_VALUE }) @PreAuthorize("hasRole('Editor')") @ResponseStatus(HttpStatus.OK) @ApiResponses(value = { @ApiResponse(code = 200, message = "The editor form."), @ApiResponse(code = 403, message = ApiParams.API_RESPONSE_NOT_ALLOWED_CAN_EDIT) }) @ResponseBody public Element saveEdits( @ApiParam(value = API_PARAM_RECORD_UUID, required = true) @PathVariable String metadataUuid, @ApiParam(value = "Tab") @RequestParam(defaultValue = "simple") String tab, @RequestParam(defaultValue = "false") boolean withAttributes, @RequestParam(defaultValue = "false") boolean withValidationErrors, @RequestParam(defaultValue = "false") boolean minor, @ApiParam(value = "Save current edits.") @RequestParam(defaultValue = "false") boolean commit, @ApiParam(value = "Save and terminate session.") @RequestParam(defaultValue = "false") boolean terminate, @ApiParam(value = "Record as XML. TODO: rename xml") @RequestParam(defaultValue = "") String data, @ApiIgnore @ApiParam(hidden = true) @RequestParam Map<String, String> allRequestParams, HttpServletRequest request, @ApiIgnore @ApiParam(hidden = true) HttpSession httpSession) throws Exception { AbstractMetadata metadata = ApiUtils.canEditRecord(metadataUuid, request); ServiceContext context = ApiUtils.createServiceContext(request); AjaxEditUtils ajaxEditUtils = new AjaxEditUtils(context); // ajaxEditUtils.preprocessUpdate(allRequestParams, context); ApplicationContext applicationContext = ApplicationContextHolder.get(); DataManager dataMan = applicationContext.getBean(DataManager.class); UserSession session = ApiUtils.getUserSession(httpSession); IMetadataValidator validator = applicationContext.getBean(IMetadataValidator.class); String id = String.valueOf(metadata.getId()); String isTemplate = allRequestParams.get(Params.TEMPLATE); // boolean finished = config.getValue(Params.FINISHED, "no").equals("yes"); // boolean forget = config.getValue(Params.FORGET, "no").equals("yes"); // boolean commit = config.getValue(Params.START_EDITING_SESSION, "no").equals("yes"); // TODO: Use map only to avoid this conversion Element params = new Element("request"); Map<String, String> forwardedParams = new HashMap<>(); for (Map.Entry<String, String> e : allRequestParams.entrySet()) { params.addContent(new Element(e.getKey()).setText(e.getValue())); if (!e.getKey().startsWith("_")) { forwardedParams.put(e.getKey(), e.getValue()); } } int iLocalId = Integer.parseInt(id); dataMan.setTemplateExt(iLocalId, MetadataType.lookup(isTemplate)); //--- use StatusActionsFactory and StatusActions class to possibly //--- change status as a result of this edit (use onEdit method) StatusActionsFactory saf = context.getBean(StatusActionsFactory.class); StatusActions sa = saf.createStatusActions(context); sa.onEdit(iLocalId, minor); Element beforeMetadata = dataMan.getMetadata(context, String.valueOf(metadata.getId()), false, false, false); if (StringUtils.isNotEmpty(data)) { Element md = Xml.loadString(data, false); String changeDate = null; boolean updateDateStamp = !minor; boolean ufo = true; boolean index = true; dataMan.updateMetadata(context, id, md, withValidationErrors, ufo, index, context.getLanguage(), changeDate, updateDateStamp); XMLOutputter outp = new XMLOutputter(); String xmlBefore = outp.outputString(beforeMetadata); String xmlAfter = outp.outputString(md); new RecordUpdatedEvent(Long.parseLong(id), session.getUserIdAsInt(), xmlBefore, xmlAfter) .publish(applicationContext); } else { ajaxEditUtils.updateContent(params, false, true); Element afterMetadata = dataMan.getMetadata(context, String.valueOf(metadata.getId()), false, false, false); XMLOutputter outp = new XMLOutputter(); String xmlBefore = outp.outputString(beforeMetadata); String xmlAfter = outp.outputString(afterMetadata); new RecordUpdatedEvent(Long.parseLong(id), session.getUserIdAsInt(), xmlBefore, xmlAfter) .publish(applicationContext); } //----------------------------------------------------------------------- //--- update element and return status // Element elResp = new Element(Jeeves.Elem.RESPONSE); // elResp.addContent(new Element(Geonet.Elem.ID).setText(id)); // elResp.addContent(new Element(Geonet.Elem.SHOWVALIDATIONERRORS) // .setText(String.valueOf(withValidationErrors))); //// boolean justCreated = Util.getParam(params, Params.JUST_CREATED, null) != null; //// if (justCreated) { //// elResp.addContent(new Element(Geonet.Elem.JUSTCREATED).setText("true")); //// } // elResp.addContent(new Element(Params.MINOREDIT).setText(String.valueOf(minor))); //--- if finished then remove the XML from the session if ((commit) && (!terminate)) { return null; } if (terminate) { SettingManager sm = context.getBean(SettingManager.class); boolean forceValidationOnMdSave = sm.getValueAsBool("metadata/workflow/forceValidationOnMdSave"); boolean reindex = false; // Save validation if the forceValidationOnMdSave is enabled if (forceValidationOnMdSave) { validator.doValidate(metadata, context.getLanguage()); reindex = true; } boolean automaticUnpublishInvalidMd = sm .getValueAsBool("metadata/workflow/automaticUnpublishInvalidMd"); boolean isUnpublished = false; // Unpublish the metadata automatically if the setting automaticUnpublishInvalidMd is enabled and // the metadata becomes invalid if (automaticUnpublishInvalidMd) { final OperationAllowedRepository operationAllowedRepo = context .getBean(OperationAllowedRepository.class); boolean isPublic = (operationAllowedRepo.count(where(hasMetadataId(id)) .and(hasOperation(ReservedOperation.view)).and(hasGroupId(ReservedGroup.all.getId()))) > 0); if (isPublic) { final MetadataValidationRepository metadataValidationRepository = context .getBean(MetadataValidationRepository.class); boolean isInvalid = (metadataValidationRepository.count( MetadataValidationSpecs.isInvalidAndRequiredForMetadata(Integer.parseInt(id))) > 0); if (isInvalid) { isUnpublished = true; operationAllowedRepo .deleteAll(where(hasMetadataId(id)).and(hasGroupId(ReservedGroup.all.getId()))); } reindex = true; } } if (reindex) { dataMan.indexMetadata(id, true, null); } ajaxEditUtils.removeMetadataEmbedded(session, id); dataMan.endEditingSession(id, session); if (isUnpublished) { throw new IllegalStateException(String.format( "Record saved but as it was invalid at the end of " + "the editing session. The public record '%s' was unpublished.", metadata.getUuid())); } else { return null; } } // if (!finished && !forget && commit) { // dataMan.startEditingSession(context, id); // } Element elMd = new AjaxEditUtils(context).getMetadataEmbedded(context, String.valueOf(id), true, withValidationErrors); return buildEditorForm(tab, httpSession, forwardedParams, request, metadata.getId(), elMd, metadata.getDataInfo().getSchemaId(), withValidationErrors, context, applicationContext, false, false); } @ApiOperation(value = "Cancel edits", notes = "Cancel current editing session.", nickname = "cancelEdits") @RequestMapping(value = "/{metadataUuid}/editor", method = RequestMethod.DELETE, consumes = { MediaType.ALL_VALUE }, produces = { MediaType.APPLICATION_XML_VALUE }) @PreAuthorize("hasRole('Editor')") @ResponseStatus(HttpStatus.NO_CONTENT) @ApiResponses(value = { @ApiResponse(code = 204, message = "Editing session cancelled."), @ApiResponse(code = 403, message = ApiParams.API_RESPONSE_NOT_ALLOWED_CAN_EDIT) }) @ResponseBody public void cancelEdits( @ApiParam(value = API_PARAM_RECORD_UUID, required = true) @PathVariable String metadataUuid, @ApiIgnore @ApiParam(hidden = true) @RequestParam Map<String, String> allRequestParams, HttpServletRequest request, @ApiIgnore @ApiParam(hidden = true) HttpSession httpSession) throws Exception { AbstractMetadata metadata = ApiUtils.canEditRecord(metadataUuid, request); ApplicationContext applicationContext = ApplicationContextHolder.get(); DataManager dataMan = applicationContext.getBean(DataManager.class); ServiceContext context = ApiUtils.createServiceContext(request); dataMan.cancelEditingSession(context, String.valueOf(metadata.getId())); } @ApiOperation(value = "Add element", notes = "", nickname = "addElement") @RequestMapping(value = "/{metadataUuid}/editor/elements", method = RequestMethod.PUT, consumes = { MediaType.ALL_VALUE }, produces = { MediaType.APPLICATION_XML_VALUE }) @PreAuthorize("hasRole('Editor')") @ResponseStatus(HttpStatus.OK) @ApiResponses(value = { @ApiResponse(code = 200, message = "Element added."), @ApiResponse(code = 403, message = ApiParams.API_RESPONSE_NOT_ALLOWED_CAN_EDIT) }) @ResponseBody public Element addElement( @ApiParam(value = API_PARAM_RECORD_UUID, required = true) @PathVariable String metadataUuid, @ApiParam(value = "Reference of the insertion point.", required = true) @RequestParam String ref, @ApiParam(value = "Name of the element to add (with prefix)", required = true) @RequestParam String name, @ApiParam(value = "Use geonet:attribute for attributes or child name.", required = false) @RequestParam(required = false) String child, @ApiParam(value = "Should attributes be shown on the editor snippet?", required = false) @RequestParam(defaultValue = "false") boolean displayAttributes, @ApiIgnore @ApiParam(hidden = true) @RequestParam Map<String, String> allRequestParams, HttpServletRequest request, @ApiIgnore @ApiParam(hidden = true) HttpSession httpSession) throws Exception { AbstractMetadata metadata = ApiUtils.canEditRecord(metadataUuid, request); ApplicationContext applicationContext = ApplicationContextHolder.get(); ServiceContext context = ApiUtils.createServiceContext(request); // -- build the element to be added // -- Here we do mark the element that is added // -- then we traverse up the tree to the root // -- clone from the root and return the clone // -- this is done so that the style sheets have // -- access to important information like the // -- document language and other locales // -- this is important for multilingual editing // -- // -- Note that the metadata-embedded.xsl stylesheet // -- only applies the templating to the added element, not to // -- the entire metadata so performance should not be a big issue Element elResp = new AjaxEditUtils(context).addElementEmbedded(ApiUtils.getUserSession(httpSession), String.valueOf(metadata.getId()), ref, name, child); EditLib.tagForDisplay(elResp); Element md = (Element) findRoot(elResp).clone(); EditLib.removeDisplayTag(elResp); return buildEditorForm(allRequestParams.get("currTab"), httpSession, allRequestParams, request, metadata.getId(), md, metadata.getDataInfo().getSchemaId(), false, context, applicationContext, true, true); } @ApiOperation(value = "Reorder element", notes = "", nickname = "reorderElement") @RequestMapping(value = "/{metadataUuid}/editor/elements/{direction}", method = RequestMethod.PUT, consumes = { MediaType.ALL_VALUE }, produces = { MediaType.APPLICATION_XML_VALUE }) @PreAuthorize("hasRole('Editor')") @ResponseStatus(HttpStatus.CREATED) @ApiResponses(value = { @ApiResponse(code = 201, message = "Element reordered."), @ApiResponse(code = 403, message = ApiParams.API_RESPONSE_NOT_ALLOWED_CAN_EDIT) }) @ResponseBody public void addElement( @ApiParam(value = API_PARAM_RECORD_UUID, required = true) @PathVariable String metadataUuid, @ApiParam(value = "Reference of the element to move.", required = true) @RequestParam String ref, @ApiParam(value = "Direction", required = true) @PathVariable Direction direction, @ApiParam(value = "Should attributes be shown on the editor snippet?", required = false) @RequestParam(defaultValue = "false") boolean displayAttributes, @ApiIgnore @ApiParam(hidden = true) @RequestParam Map<String, String> allRequestParams, HttpServletRequest request, @ApiIgnore @ApiParam(hidden = true) HttpSession httpSession) throws Exception { AbstractMetadata metadata = ApiUtils.canEditRecord(metadataUuid, request); ServiceContext context = ApiUtils.createServiceContext(request); new AjaxEditUtils(context).swapElementEmbedded(ApiUtils.getUserSession(httpSession), String.valueOf(metadata.getId()), ref, direction == Direction.down); } @ApiOperation(value = "Delete element", notes = "", nickname = "deleteElement") @RequestMapping(value = "/{metadataUuid}/editor/elements", method = RequestMethod.DELETE, consumes = { MediaType.ALL_VALUE }, produces = { MediaType.APPLICATION_XML_VALUE }) @PreAuthorize("hasRole('Editor')") @ResponseStatus(HttpStatus.NO_CONTENT) @ApiResponses(value = { @ApiResponse(code = 204, message = "Element removed."), @ApiResponse(code = 403, message = ApiParams.API_RESPONSE_NOT_ALLOWED_CAN_EDIT) }) @ResponseBody public void deleteElement( @ApiParam(value = API_PARAM_RECORD_UUID, required = true) @PathVariable String metadataUuid, @ApiParam(value = "Reference of the element to remove.", required = true) @RequestParam String[] ref, @ApiParam(value = "Name of the parent.", required = true) @RequestParam String parent, @ApiParam(value = "Should attributes be shown on the editor snippet?", required = false) @RequestParam(defaultValue = "false") boolean displayAttributes, HttpServletRequest request, @ApiIgnore @ApiParam(hidden = true) HttpSession httpSession) throws Exception { AbstractMetadata metadata = ApiUtils.canEditRecord(metadataUuid, request); ServiceContext context = ApiUtils.createServiceContext(request); String id = String.valueOf(metadata.getId()); for (int i = 0; i < ref.length; i++) { new AjaxEditUtils(context).deleteElementEmbedded(ApiUtils.getUserSession(httpSession), id, ref[i], parent); } } @ApiOperation(value = "Delete attribute", notes = "", nickname = "deleteAttribute") @RequestMapping(value = "/{metadataUuid}/editor/attributes", method = RequestMethod.DELETE, consumes = { MediaType.ALL_VALUE }, produces = { MediaType.APPLICATION_XML_VALUE }) @PreAuthorize("hasRole('Editor')") @ResponseStatus(HttpStatus.NO_CONTENT) @ApiResponses(value = { @ApiResponse(code = 204, message = "Attribute removed."), @ApiResponse(code = 403, message = ApiParams.API_RESPONSE_NOT_ALLOWED_CAN_EDIT) }) @ResponseBody public void deleteAttribute( @ApiParam(value = API_PARAM_RECORD_UUID, required = true) @PathVariable String metadataUuid, @ApiParam(value = "Reference of the attribute to remove.", required = true) @RequestParam String ref, @ApiParam(value = "Should attributes be shown on the editor snippet?", required = false) @RequestParam(defaultValue = "false") boolean displayAttributes, HttpServletRequest request, @ApiIgnore @ApiParam(hidden = true) HttpSession httpSession) throws Exception { AbstractMetadata metadata = ApiUtils.canEditRecord(metadataUuid, request); ServiceContext context = ApiUtils.createServiceContext(request); new AjaxEditUtils(context).deleteAttributeEmbedded(ApiUtils.getUserSession(httpSession), String.valueOf(metadata.getId()), ref); } private Element findRoot(Element element) { if (element.isRootElement() || element.getParentElement() == null) return element; return findRoot(element.getParentElement()); } /** * This is a lightweight representation of the * legacy Jeeves XML processed by XSLT. Only * element required for the editor are created. */ private Element buildEditorForm(String tab, HttpSession session, Map<String, String> allRequestParams, HttpServletRequest request, int id, Element xml, String schema, boolean showValidationErrors, ServiceContext context, ApplicationContext applicationContext, boolean isEmbedded, boolean embedded) throws Exception { UserSession userSession = ApiUtils.getUserSession(session); Element root = buildResourceDocument(applicationContext, context, userSession); root.addContent(xml); Element gui = root.getChild("gui"); gui.addContent(new Element("currTab").setText(tab)); // This flag is used to generate top tool bar or not gui.addContent(new Element("reqService").setText(embedded ? "embedded" : "md.edit")); String iso3langCode = languageUtils.getIso3langCode(request.getLocales()); gui.addContent(new Element("language").setText(iso3langCode)); gui.addContent(getSchemaStrings(schema, context)); Element requestParams = new Element("request"); for (Map.Entry<String, String> e : allRequestParams.entrySet()) { requestParams.addContent(new Element(e.getKey()).setText(e.getValue())); } root.addContent(requestParams); GeonetworkDataDirectory dataDirectory = applicationContext.getBean(GeonetworkDataDirectory.class); Path xslt = dataDirectory.getWebappDir() .resolve(isEmbedded ? "xslt/ui-metadata/edit/edit-embedded.xsl" : "xslt/ui-metadata/edit/edit.xsl"); return Xml.transform(root, xslt); } private Element buildResourceDocument(ApplicationContext applicationContext, ServiceContext context, UserSession userSession) throws JDOMException, SQLException, IOException { // <gui> // Unused now // <xml name="strings" file="xml/strings.xml"/> // Unused now // <call name="isolanguages" class="org.fao.geonet.guiservices.isolanguages.Get"/> // <call name="session" class="jeeves.guiservices.session.Get"/> // <call name="env" class="org.fao.geonet.guiservices.util.Env"/> // <call name="systemConfig" class="org.fao.geonet.services.config.Get"/> // <call name="results" class="org.fao.geonet.guiservices.search.GetResultsInfo"/> // <call name="schemalist" class="org.fao.geonet.guiservices.schemas.Get"/> // <call name="svnmanager" class="org.fao.geonet.guiservices.util.GetSvnDetails"/> // // <!-- this service adds labels and codelists from all schemas --> // <call name="schemas" class="org.fao.geonet.guiservices.schemas.GetSchemaInfo"/> // </gui> Element root = new Element("root"); Element gui = new Element("gui"); gui.addContent(applicationContext.getBean(SettingManager.class).getAllAsXML(true)); gui.addContent(getSessionAsXML(userSession)); ThesaurusManager th = applicationContext.getBean(ThesaurusManager.class); gui.addContent(new Element("thesaurus").addContent(th.buildResultfromThTable(context))); // TODO: Add request parameters // <output sheet="../xslt/ui-metadata/edit/edit.xsl"> // <call name="thesaurus" class=".services.thesaurus.GetList"/> // <call name="currTab" class=".guiservices.util.GetCurrentMDTab"/> // <xml name="i18n" file="xml/i18n.xml"/> root.addContent(gui); return root; } @Autowired SchemaManager schemaManager; public Element getSchemaStrings(String schemaToLoad, ServiceContext context) throws Exception { Element schemas = new Element("schemas"); for (String schema : schemaManager.getSchemas()) { // Load schema and schema dependency localization files if (schema.equals(schemaToLoad) || schemaToLoad.startsWith(schema) || schemaManager.getDependencies(schemaToLoad).contains(schema)) { try { Map<String, XmlFile> schemaInfo = schemaManager.getSchemaInfo(schema); for (Map.Entry<String, XmlFile> entry : schemaInfo.entrySet()) { XmlFile xf = entry.getValue(); String fname = entry.getKey(); Element response = xf.exec(new Element("junk"), context); response.setName(FilenameUtils.removeExtension(fname)); response.removeAttribute("noNamespaceSchemaLocation", Geonet.Namespaces.XSI); Element schemaElem = new Element(schema); schemaElem.addContent(response); schemas.addContent(schemaElem); } } catch (Exception e) { context.error("Failed to load localization file for schema " + schema + ": " + e.getMessage()); e.printStackTrace(); } } } return schemas; } }