diff --git a/.classpath b/.classpath index fcd4e72..d64ebcb 100644 --- a/.classpath +++ b/.classpath @@ -6,6 +6,12 @@ + + + + + + diff --git a/pom.xml b/pom.xml index 2030bd4..aabb261 100644 --- a/pom.xml +++ b/pom.xml @@ -99,6 +99,11 @@ provided + + com.google.guava + guava + + junit diff --git a/src/main/java/org/gcube/common/metadataprofilediscovery/MetadataProfileReader.java b/src/main/java/org/gcube/common/metadataprofilediscovery/MetadataProfileReader.java index 2ee96dd..ce30511 100644 --- a/src/main/java/org/gcube/common/metadataprofilediscovery/MetadataProfileReader.java +++ b/src/main/java/org/gcube/common/metadataprofilediscovery/MetadataProfileReader.java @@ -28,10 +28,10 @@ import javax.xml.validation.Validator; import org.gcube.common.metadataprofilediscovery.bean.MetadataProfile; import org.gcube.common.metadataprofilediscovery.jaxb.MetadataFormat; +import org.gcube.common.metadataprofilediscovery.jaxb.NamespaceCategories; import org.gcube.common.metadataprofilediscovery.jaxb.NamespaceCategory; import org.gcube.common.metadataprofilediscovery.reader.MetadataFormatDiscovery; import org.gcube.common.metadataprofilediscovery.reader.MetadataFormatReader; -import org.gcube.common.metadataprofilediscovery.reader.NamespaceCategoryReader; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.scope.impl.ScopeBean; import org.slf4j.Logger; @@ -169,8 +169,8 @@ public class MetadataProfileReader implements MetadataProfileDiscovery { if (namespaceCategories == null) namespaceCategories = new ArrayList(); - NamespaceCategoryReader rd = new NamespaceCategoryReader(scope); - namespaceCategories.addAll(rd.getNamespaces().getNamespaceCategories()); + NamespaceCategories ncCache = NamespaceCategoriesCache.loadNamespaces(scope.toString()); + namespaceCategories.addAll(ncCache.getNamespaceCategories()); } } catch (Exception e) { logger.warn("An error occurred during read namespaces for categories: ", e); diff --git a/src/main/java/org/gcube/common/metadataprofilediscovery/NamespaceCategoriesCache.java b/src/main/java/org/gcube/common/metadataprofilediscovery/NamespaceCategoriesCache.java new file mode 100644 index 0000000..dcbec15 --- /dev/null +++ b/src/main/java/org/gcube/common/metadataprofilediscovery/NamespaceCategoriesCache.java @@ -0,0 +1,145 @@ +/** + * + */ +package org.gcube.common.metadataprofilediscovery; + +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; + +import org.gcube.common.metadataprofilediscovery.jaxb.NamespaceCategories; +import org.gcube.common.metadataprofilediscovery.reader.NamespaceCategoryReader; +import org.gcube.common.scope.api.ScopeProvider; +import org.gcube.common.scope.impl.ScopeBean; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import com.google.common.cache.RemovalListener; +import com.google.common.cache.RemovalNotification; + +/** + * The Class NamespaceCategoriesCache. + * + * @author Francesco Mangiacrapa at ISTI-CNR francesco.mangiacrapa@isti.cnr.it + * + * Mar 3, 2022 + */ +public class NamespaceCategoriesCache { + + private static Logger LOG = LoggerFactory.getLogger(NamespaceCategoriesCache.class); + private static LoadingCache namespaces; + + static { + + CacheLoader loader = new CacheLoader() { + + @Override + public NamespaceCategories load(String scope) throws Exception { + + LOG.info("Loading the NamespaceCategories cache for scope: {}", scope); + NamespaceCategories namespacesCat = loadNamespaces(scope); + if (namespacesCat != null) + LOG.info("Returning {} for the scope name: {}", NamespaceCategories.class.getSimpleName(), scope); + else { + LOG.info("No NamespaceCategories obj for scope {}", scope); + } + + return namespacesCat; + } + + }; + + RemovalListener removalListener = new RemovalListener() { + + @Override + public void onRemoval(RemovalNotification arg0) { + + LOG.debug("cache expired"); + } + }; + + namespaces = CacheBuilder.newBuilder().maximumSize(300).expireAfterWrite(30, TimeUnit.MINUTES) + .removalListener(removalListener).build(loader); + + } + + /** + * Populate the cache. + * + * @param scope the scope + */ + private static void populateTheCache(ScopeBean scope) { + String origScope = null; + String instScope = scope.toString(); + try { + origScope = ScopeProvider.instance.get(); + // Populating the cache by using the detachedres-library + ScopeProvider.instance.set(scope.toString()); + LOG.info("Trying to populate the Namespaces cache in the scope: "+instScope); + NamespaceCategoryReader rd = new NamespaceCategoryReader(scope); + namespaces.put(instScope, rd.getNamespaces()); + } catch (Exception e) { + // SILENT + } finally { + + if (origScope != null && !origScope.equals(scope.toString())) { + // Setting original scope + ScopeProvider.instance.set(scope.toString()); + } + + } + } + + /** + * Gets the VRE obj for input VRE name. + * + * @param scope the scope + * @return the vre + * @throws ExecutionException the execution exception + */ + public static NamespaceCategories get(String scope) throws ExecutionException { + + try { + return namespaces.get(scope); + } catch (Exception e) { + LOG.info("Error on getting NamespaceCategories obj for scope {}. Is the key {} not found in the cache?", + scope, namespaces); + throw e; + } + } + + /** + * Load VRE obj for VRE name. + * + * @param scope the scope + * @return the vre + */ + protected static NamespaceCategories loadNamespaces(String scope) { + NamespaceCategories namespacesCategories = namespaces.getIfPresent(scope); + + // THIS CHECK SHOULD NOT BE NEEDED + if (namespacesCategories == null) { + LOG.info("loading Catalogue Namespaces for scope: {}",scope); + ScopeBean scopeB = new ScopeBean(scope); + populateTheCache(scopeB); + namespacesCategories = namespaces.getIfPresent(scope); + LOG.info("NamespaceCategories populated correclty with scope: {}",scope); + }else { + LOG.info("NamespaceCategories cache already populated with scope: {}, returning cached NamespaceCategories",scope); + } + + return namespacesCategories; + } + + /** + * Gets the cache. + * + * @return the cache + */ + public LoadingCache getCache() { + return namespaces; + } + +} diff --git a/src/main/java/org/gcube/common/metadataprofilediscovery/reader/NamespaceCategoryReader.java b/src/main/java/org/gcube/common/metadataprofilediscovery/reader/NamespaceCategoryReader.java index 95303bf..5b7c158 100644 --- a/src/main/java/org/gcube/common/metadataprofilediscovery/reader/NamespaceCategoryReader.java +++ b/src/main/java/org/gcube/common/metadataprofilediscovery/reader/NamespaceCategoryReader.java @@ -8,12 +8,21 @@ import static org.gcube.resources.discovery.icclient.ICFactory.client; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.StringReader; +import java.io.StringWriter; import java.util.List; import javax.xml.bind.JAXBContext; import javax.xml.bind.Unmarshaller; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathFactory; import org.gcube.common.metadataprofilediscovery.jaxb.NamespaceCategories; import org.gcube.common.resources.gcore.utils.XPathHelper; @@ -23,7 +32,9 @@ import org.gcube.resources.discovery.client.queries.api.Query; import org.gcube.resources.discovery.client.queries.impl.QueryBox; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; import org.w3c.dom.Node; +import org.w3c.dom.NodeList; import org.xml.sax.InputSource; @@ -35,6 +46,8 @@ import org.xml.sax.InputSource; */ public class NamespaceCategoryReader { + private static final String PATH_RESOURCE_PROFILE_BODY_NAMESPACES = "/Resource/Profile/Body/namespaces"; + private static Logger logger = LoggerFactory.getLogger(NamespaceCategoryReader.class); private static final String GENERIC_RESOURCE_NAMESPACES_NAME = "Namespaces Catalogue Categories"; @@ -89,12 +102,11 @@ public class NamespaceCategoryReader { String theResource = null; try{ theResource = appProfile.get(0); - logger.debug("Resource (Namespaces Catalogue Categories) found"); + logger.debug("Resource "+GENERIC_RESOURCE_NAMESPACES_NAME+" found"); + logger.trace("Resource "+GENERIC_RESOURCE_NAMESPACES_NAME+" is: "+theResource); DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - Node node = docBuilder.parse(new InputSource(new StringReader(theResource))).getDocumentElement(); - XPathHelper helper = new XPathHelper(node); - logger.debug("Unmarshalling it.."); - readNamespaceCategoryFromResource(helper); + Document xmlDocument = docBuilder.parse(new InputSource(new StringReader(theResource))); + readNamespaceCategoryFromResource(xmlDocument); }catch(Exception e){ logger.error("Error while parsing Resource "+theResource+" from the infrastructure, the scope is "+scopeString,e); } @@ -109,6 +121,52 @@ public class NamespaceCategoryReader { } } + /** + * Read namespace category from resource. + * + * @param helper the helper + * @throws Exception the exception + */ + private void readNamespaceCategoryFromResource(Document xmlDocument) throws Exception{ + + try { + + XPath xPath = XPathFactory.newInstance().newXPath(); + String expression = PATH_RESOURCE_PROFILE_BODY_NAMESPACES; + NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(xmlDocument, XPathConstants.NODESET); + + String namespaceSources = getNodeString(nodeList.item(0)); + + JAXBContext jaxbContext = JAXBContext.newInstance(NamespaceCategories.class); + Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); + + if(namespaceSources==null || namespaceSources.length()==0){ + throw new Exception("Resource does not contain ... in the body"); + } + + logger.debug("Unmarshalling document path "+PATH_RESOURCE_PROFILE_BODY_NAMESPACES +" to "+NamespaceCategories.class.getSimpleName()); + InputStream stream = new ByteArrayInputStream(namespaceSources.getBytes()); + namespaces = (NamespaceCategories) jaxbUnmarshaller.unmarshal(stream); + + }catch(Exception e){ + String error = "An error occurred in readNamespaceCategoryFromResource " + e.getMessage(); + logger.error("An error occurred in readNamespaceCategoryFromResource ", e); + throw new Exception(error); + } + } + + private String getNodeString(Node node) { + try { + StringWriter writer = new StringWriter(); + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.transform(new DOMSource(node), new StreamResult(writer)); + String output = writer.toString(); + return output; + } catch (TransformerException e) { + e.printStackTrace(); + } + return node.getTextContent(); + } /** * Read namespace category from resource. @@ -119,8 +177,13 @@ public class NamespaceCategoryReader { private void readNamespaceCategoryFromResource(XPathHelper helper) throws Exception{ try { + + if(helper==null) { + logger.warn("**************************\n\nXpathHelper is null!!!!\n\n"); + } + - List namespaceSources = helper.evaluate("/Resource/Profile/Body/namespaces"); + List namespaceSources = helper.evaluate(PATH_RESOURCE_PROFILE_BODY_NAMESPACES); JAXBContext jaxbContext = JAXBContext.newInstance(NamespaceCategories.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); diff --git a/src/test/java/org/gcube/common/metadataprofilediscovery/TestMetadataFormatReader.java b/src/test/java/org/gcube/common/metadataprofilediscovery/TestMetadataFormatReader.java index b3359be..d81e312 100644 --- a/src/test/java/org/gcube/common/metadataprofilediscovery/TestMetadataFormatReader.java +++ b/src/test/java/org/gcube/common/metadataprofilediscovery/TestMetadataFormatReader.java @@ -3,41 +3,50 @@ */ package org.gcube.common.metadataprofilediscovery; -import org.gcube.common.metadataprofilediscovery.bean.MetadataProfile; -import org.gcube.common.metadataprofilediscovery.jaxb.NamespaceCategory; +import java.io.InputStream; + +import org.gcube.common.metadataprofilediscovery.jaxb.MetadataField; +import org.gcube.common.metadataprofilediscovery.jaxb.MetadataFormat; +import org.gcube.common.metadataprofilediscovery.reader.MetadataFormatReader; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.scope.impl.ScopeBean; - /** * - * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it - * Jun 8, 2016 + * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it Jun 8, 2016 */ public class TestMetadataFormatReader { - //@Test +// @Test public void test() { String scopeString = "/gcube/devsec/devVRE"; - final ScopeBean scope = new ScopeBean(scopeString); - MetadataProfileReader reader; + final ScopeBean scope = new ScopeBean(scopeString); + MetadataFormatReader reader; try { ScopeProvider.instance.set(scopeString); - reader = new MetadataProfileReader("GeoNaMetadata"); - - int i = 0; - for (MetadataProfile metadataProfile : reader.getListOfMetadataProfiles()) { - System.out.println(i++ +")"+metadataProfile); - } - - i = 0; - for (NamespaceCategory namespaceCategory : reader.getListOfNamespaceCategories()) { - System.out.println(i++ +")"+namespaceCategory); - } + reader = new MetadataFormatReader(scope, "0d29d7a9-d779-478c-a13d-d70708dc66c4"); + System.out.println(reader.getMetadataFormat()); } catch (Exception e) { e.printStackTrace(); } } + // @Test + public void testReadInputStream() { + String fileNameMeatadataProfile = "HarvestedObject.xml"; + try { + InputStream in = ClassLoader.getSystemResourceAsStream(fileNameMeatadataProfile); + // InputStream in = + // TestMetadataFormatReader.class.getResourceAsStream(fileNameMeatadataProfile); + MetadataFormat mf = MetadataProfileReader.toMetadataFormat(in); + System.out.println("Source: " + mf.getMetadataSource()); + + for (MetadataField field : mf.getMetadataFields()) { + System.out.println(field); + } + } catch (Exception e) { + e.printStackTrace(); + } + } } diff --git a/src/test/java/org/gcube/common/metadataprofilediscovery/TestMetadataProfileReader.java b/src/test/java/org/gcube/common/metadataprofilediscovery/TestMetadataProfileReader.java index 48f0ca9..d9a3a46 100644 --- a/src/test/java/org/gcube/common/metadataprofilediscovery/TestMetadataProfileReader.java +++ b/src/test/java/org/gcube/common/metadataprofilediscovery/TestMetadataProfileReader.java @@ -3,51 +3,46 @@ */ package org.gcube.common.metadataprofilediscovery; -import java.io.InputStream; - -import org.gcube.common.metadataprofilediscovery.jaxb.MetadataField; -import org.gcube.common.metadataprofilediscovery.jaxb.MetadataFormat; -import org.gcube.common.metadataprofilediscovery.reader.MetadataFormatReader; +import org.gcube.common.metadataprofilediscovery.bean.MetadataProfile; +import org.gcube.common.metadataprofilediscovery.jaxb.NamespaceCategory; import org.gcube.common.scope.api.ScopeProvider; import org.gcube.common.scope.impl.ScopeBean; - +import org.junit.Test; /** * - * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it - * Jun 8, 2016 + * @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it Jun 8, 2016 */ public class TestMetadataProfileReader { -// @Test + //@Test public void test() { String scopeString = "/gcube/devsec/devVRE"; - final ScopeBean scope = new ScopeBean(scopeString); - MetadataFormatReader reader; - try { - ScopeProvider.instance.set(scopeString); - reader = new MetadataFormatReader(scope, "0d29d7a9-d779-478c-a13d-d70708dc66c4"); - System.out.println(reader.getMetadataFormat()); - } catch (Exception e) { - e.printStackTrace(); - } - } - - //@Test - public void testReadInputStream() { - String fileNameMeatadataProfile = "HarvestedObject.xml"; - try { - InputStream in = ClassLoader.getSystemResourceAsStream(fileNameMeatadataProfile); - //InputStream in = TestMetadataFormatReader.class.getResourceAsStream(fileNameMeatadataProfile); - MetadataFormat mf = MetadataProfileReader.toMetadataFormat(in); - System.out.println("Source: "+mf.getMetadataSource()); - - for (MetadataField field : mf.getMetadataFields()) { - System.out.println(field); + final ScopeBean scope = new ScopeBean(scopeString); + + String[] genericResourceNames = new String[] {"Informazioni_di_progetto","Relazione_di_Scavo"}; + + for (int i = 0; i < 2; i++) { + MetadataProfileReader reader; + try { + ScopeProvider.instance.set(scope.toString()); + reader = new MetadataProfileReader("GeoNaMetadata",genericResourceNames[i]); + + int j = 0; + for (MetadataProfile metadataProfile : reader.getListOfMetadataProfiles()) { + System.out.println(j++ + ")" + metadataProfile); + } + + j = 0; + for (NamespaceCategory namespaceCategory : reader.getListOfNamespaceCategories()) { + System.out.println(j++ + ")" + namespaceCategory); + } + } catch (Exception e) { + e.printStackTrace(); } - } catch (Exception e) { - e.printStackTrace(); } + } + }