import java.util.*;
public class Importer {
public static List<String> doImport(final Element params, final ServiceContext context,
final File mefFile, final String stylePath) throws Exception {
final DataManager dm = context.getBean(DataManager.class);
// Load preferred schema and set to iso19139 by default
String preferredSchema = context.getBean(ServiceConfig.class).getMandatoryValue("preferredSchema");
if (preferredSchema == null) {
preferredSchema = "iso19139";
}
final List<String> metadataIdMap = new ArrayList<String>();
final List<Element> md = new ArrayList<Element>();
final List<Element> fc = new ArrayList<Element>();
// Try to define MEF version from mef file not from parameter
String fileType = Util.getParam(params, "file_type", "mef");
if (fileType.equals("mef")) {
MEFLib.Version version = MEFLib.getMEFVersion(mefFile);
if (version != null && version.equals(MEFLib.Version.V2)) {
fileType = "mef2";
}
}
IVisitor visitor;
if (fileType.equals("single"))
visitor = new XmlVisitor();
else if (fileType.equals("mef"))
visitor = new MEFVisitor();
else if (fileType.equals("mef2"))
visitor = new MEF2Visitor();
else
throw new BadArgumentException("Bad file type parameter.");
// --- import metadata from MEF, Xml, ZIP files
final String finalPreferredSchema = preferredSchema;
MEFLib.visit(mefFile, visitor, new IMEFVisitor() {
public void handleMetadata(Element metadata, int index)
throws Exception {
if(Log.isDebugEnabled(Geonet.MEF))
Log.debug(Geonet.MEF, "Collecting metadata:\n" + Xml.getString(metadata));
md.add(index, metadata);
}
public void handleMetadataFiles(File[] Files, Element info, int index)
throws Exception {
String infoSchema = "_none_";
if (info != null && info.getContentSize() != 0) {
Element general = info.getChild("general");
if (general != null && general.getContentSize() != 0) {
if (general.getChildText("schema") != null) {
infoSchema = general.getChildText("schema");
}
}
}
String lastUnknownMetadataFolderName=null;
if(Log.isDebugEnabled(Geonet.MEF))
Log.debug(Geonet.MEF, "Multiple metadata files");
if(Log.isDebugEnabled(Geonet.MEF))
Log.debug(Geonet.MEF, "info.xml says schema should be "+infoSchema);
Element metadataValidForImport;
Map<String,Pair<String,Element>> mdFiles = new HashMap<String,Pair<String,Element>>();
for (File file : Files) {
if (file != null && !file.isDirectory()) {
Element metadata = Xml.loadFile(file);
try {
String metadataSchema = dm.autodetectSchema(metadata, null);
// If local node doesn't know metadata
// schema try to load next xml file.
if (metadataSchema == null) {
continue;
}
String currFile = "Found metadata file " + file.getParentFile().getParentFile().getName() + File.separator + file.getParentFile().getName() + File.separator + file.getName();
mdFiles.put(metadataSchema,Pair.read(currFile,metadata));
} catch (NoSchemaMatchesException e) {
// Important folder name to identify metadata should be ../../
lastUnknownMetadataFolderName=file.getParentFile().getParentFile().getName() + File.separator + file.getParentFile().getName() + File.separator;
Log.debug(Geonet.MEF, "No schema match for "
+ lastUnknownMetadataFolderName + file.getName()
+ ".");
}
}
}
if (mdFiles.size() == 0) {
throw new BadFormatEx("No valid metadata file found" + ((lastUnknownMetadataFolderName==null)?"":(" in " + lastUnknownMetadataFolderName)) + ".");
}
// 1st: Select metadata with schema in info file
Pair<String,Element> mdInform = mdFiles.get(infoSchema);
if (mdInform != null) {
if (Log.isDebugEnabled(Geonet.MEF)) {
Log.debug(Geonet.MEF, mdInform.one()
+ " with info.xml schema (" + infoSchema + ").");
}
metadataValidForImport = mdInform.two();
handleMetadata(metadataValidForImport, index);
return;
}
// 2nd: Select metadata with preferredSchema
mdInform = mdFiles.get(finalPreferredSchema);
if (mdInform != null) {
if (Log.isDebugEnabled(Geonet.MEF)) {
Log.debug(Geonet.MEF, mdInform.one()
+ " with preferred schema (" + finalPreferredSchema + ").");
}
metadataValidForImport = mdInform.two();
handleMetadata(metadataValidForImport, index);
return;
}
// Lastly: Select the first metadata in the map
String metadataSchema = (String)mdFiles.keySet().toArray()[0];
mdInform = mdFiles.get(metadataSchema);
if (Log.isDebugEnabled(Geonet.MEF)) {
Log.debug(Geonet.MEF, mdInform.one()
+ " with known schema (" + metadataSchema + ").");
}
metadataValidForImport = mdInform.two();
// Import valid metadata
handleMetadata(metadataValidForImport, index);
}
// --------------------------------------------------------------------
public void handleFeatureCat(Element featureCat, int index)
throws Exception {
if (featureCat != null) {
if(Log.isDebugEnabled(Geonet.MEF))
Log.debug(Geonet.MEF, "Collecting feature catalog:\n" + Xml.getString(featureCat));
}
fc.add(index, featureCat);
}
// --------------------------------------------------------------------
/**
* Record is not a template by default. No category attached to
* record by default. No stylesheet used by default. If no site
* identifier provided, use current node id by default. No
* validation by default.
*
* If record is a template and not a MEF file always generate a new
* UUID.
*/
public void handleInfo(Element info, int index) throws Exception {
String FS = File.separator;
String uuid = null;
String createDate = null;
String changeDate = null;
String source;
String sourceName = null;
// Schema in info.xml is not used here anymore.
// It is used in handleMetadataFiles as the first option to pick a
// metadata file from those in a metadata dir in a MEF2
// String schema = null;
final MetadataType isTemplate;
String rating = null;
String popularity = null;
String groupId = null;
Element categs = null;
final Element privileges;
boolean validate = false;
// Apply a stylesheet transformation if requested
String style = Util.getParam(params, Params.STYLESHEET,
"_none_");
if (!style.equals("_none_"))
md.add(index, Xml.transform(md.get(index), stylePath
+ FS + style));
final Element metadata = md.get(index);
String schema = dm.autodetectSchema(metadata, null);
if (schema == null)
throw new Exception("Unknown schema");
// Handle non MEF files insertion
if (info.getChildren().size() == 0) {
source = Util.getParam(params, Params.SITE_ID, context.getBean(SettingManager.class).getSiteId());
isTemplate = MetadataType.lookup(Util.getParam(params, Params.TEMPLATE, "n"));
String category = Util
.getParam(params, Params.CATEGORY, "");
if (!category.equals("")) {
categs = new Element("categories");
categs.addContent((new Element("category"))
.setAttribute("name", category));
}
groupId = Util.getParam(params, Params.GROUP);
privileges = new Element("group");
privileges.addContent(new Element("operation")
.setAttribute("name", "view"));
privileges.addContent(new Element("operation")
.setAttribute("name", "editing"));
privileges.addContent(new Element("operation")
.setAttribute("name", "download"));
privileges.addContent(new Element("operation")
.setAttribute("name", "notify"));
privileges.addContent(new Element("operation")
.setAttribute("name", "dynamic"));
privileges.addContent(new Element("operation")
.setAttribute("name", "featured"));
if (isTemplate == MetadataType.METADATA) {
// Get the Metadata uuid if it's not a template.
uuid = dm.extractUUID(schema, md.get(index));
} else if (isTemplate== MetadataType.SUB_TEMPLATE) {
// Get subtemplate uuid if defined in @uuid at root
uuid = md.get(index).getAttributeValue("uuid");
}
validate = Util.getParam(params, Params.VALIDATE, "off")
.equals("on");
} else {
if(Log.isDebugEnabled(Geonet.MEF))
Log.debug(Geonet.MEF, "Collecting info file:\n" + Xml.getString(info));
categs = info.getChild("categories");
privileges = info.getChild("privileges");
Element general = info.getChild("general");
uuid = general.getChildText("uuid");
createDate = general.getChildText("createDate");
changeDate = general.getChildText("changeDate");
// If "assign" checkbox is set to true, we assign the metadata to the current catalog siteID/siteName
boolean assign = Util.getParam(params, "assign", "off")
.equals("on");
if (assign) {
if(Log.isDebugEnabled(Geonet.MEF))
Log.debug(Geonet.MEF, "Assign to local catalog");
source = context.getBean(SettingManager.class).getSiteId();
} else {
// --- If siteId is not set, set to current node
source = Util.getParam(general, Params.SITE_ID, context.getBean(SettingManager.class).getSiteId());
sourceName = general.getChildText("siteName");
if(Log.isDebugEnabled(Geonet.MEF))
Log.debug(Geonet.MEF, "Assign to catalog: " + source);
}
isTemplate = general.getChildText("isTemplate").equals("true") ? MetadataType.TEMPLATE : MetadataType.METADATA;
rating = general.getChildText("rating");
popularity = general.getChildText("popularity");
}
if (validate) {
// Validate xsd and schematron
DataManager.validateMetadata(schema, metadata, context);
}
String uuidAction = Util.getParam(params, Params.UUID_ACTION,
Params.NOTHING);
importRecord(uuid, uuidAction, md, schema, index,
source, sourceName, context, metadataIdMap, createDate,
changeDate, groupId, isTemplate);
if (fc.size() != 0 && fc.get(index) != null) {
// UUID is set as @uuid in root element
uuid = UUID.randomUUID().toString();
fc.add(index, dm.setUUID("iso19110", uuid, fc.get(index)));
//
// insert metadata
//
int userid = context.getUserSession().getUserIdAsInt();
String group = null, docType = null, title = null, category = null;
boolean ufo = false, indexImmediate = false;
String fcId = dm.insertMetadata(context, "iso19110", fc.get(index), uuid,
userid, group, source, isTemplate.codeString, docType, category, createDate, changeDate, ufo, indexImmediate);
if(Log.isDebugEnabled(Geonet.MEF))
Log.debug(Geonet.MEF, "Adding Feature catalog with uuid: " + uuid);
// Create database relation between metadata and feature
// catalog
String mdId = metadataIdMap.get(index);
final MetadataRelationRepository relationRepository = context.getBean(MetadataRelationRepository.class);
final MetadataRelation relation = new MetadataRelation();
relation.setId(new MetadataRelationId(Integer.valueOf(mdId), Integer.valueOf(fcId)));
relationRepository.save(relation);
metadataIdMap.add(fcId);
// TODO : privileges not handled for feature catalog ...
}
final int iMetadataId = Integer.valueOf(metadataIdMap.get(index));
final String finalPopularity = popularity;
final String finalRating = rating;
final Element finalCategs = categs;
final String finalGroupId = groupId;
context.getBean(MetadataRepository.class).update(iMetadataId, new Updater<Metadata>() {
@Override
public void apply(@Nonnull final Metadata metadata) {
final MetadataDataInfo dataInfo = metadata.getDataInfo();
if (finalPopularity != null) {
dataInfo.setPopularity(Integer.valueOf(finalPopularity));
}
if (finalRating != null) {
dataInfo.setRating(Integer.valueOf(finalRating));
}
dataInfo.setType(isTemplate);
metadata.getHarvestInfo().setHarvested(false);
addCategoriesToMetadata(metadata, finalCategs, context);
if (finalGroupId == null) {
Group ownerGroup = addPrivileges(context, dm, iMetadataId, privileges);
if (ownerGroup != null) {
metadata.getSourceInfo().setGroupOwner(ownerGroup.getId());
}
} else {
final OperationAllowedRepository allowedRepository = context.getBean(OperationAllowedRepository.class);
final Set<OperationAllowed> allowedSet = addOperations(context, dm, privileges, iMetadataId,
Integer.valueOf(finalGroupId));
allowedRepository.save(allowedSet);
}
}
});
String pubDir = Lib.resource.getDir(context, "public", metadataIdMap
.get(index));
String priDir = Lib.resource.getDir(context, "private", metadataIdMap
.get(index));
IO.mkdirs(new File(pubDir), "MEF Importer public resources directory for metadata "+metadataIdMap);
IO.mkdirs(new File(priDir), "MEF Importer private resources directory for metadata "+metadataIdMap);
dm.indexMetadata(metadataIdMap.get(index), false);
}
// --------------------------------------------------------------------
public void handlePublicFile(String file, String changeDate,