cancel
Showing results for 
Search instead for 
Did you mean: 

XPathMetadata Extracter broken on upgrade

telomari
Champ in-the-making
Champ in-the-making
Hi,

We have recently upgraded our version of Alfresco from 3.1 to 3.4 and in the process knocked out our custom built java extension.

We have been advised to upgrade our references from the org.alfresco.* to the springframework library however i can not find where the XPathMetaDataExtracter is referenced in the springframework library. This may not even be the issue!

our code looks as follows
package com.quark.alfresco.content.metadata.xml;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.alfresco.repo.content.metadata.xml.XPathMetadataExtracter;
import org.alfresco.service.cmr.repository.ContentReader;
import org.apache.log4j.Logger;
import org.apache.xml.resolver.tools.CatalogResolver;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class XPathWithResolverMetadataExtracter extends XPathMetadataExtracter {
   
   private CatalogResolver catalogResolver;
   private Logger logger2 = Logger.getLogger(XPathWithResolverMetadataExtracter.class);
   
   public XPathWithResolverMetadataExtracter() {
      
   }
   
   @Override
   protected Map<String, Serializable> extractRaw(ContentReader reader)
         throws Throwable {
        InputStream is = null;
        try
        {
            is = reader.getContentInputStream();
            DocumentBuilder localDocumentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            localDocumentBuilder.setEntityResolver(catalogResolver);
            Document doc = localDocumentBuilder.parse(is);
           
            listNodes(doc.getFirstChild(), "");
            Map<String, Serializable> rawProperties = processDocument(doc);
            if (logger2.isDebugEnabled())
            {
               logger2.debug("\n" +
                        "Extracted XML metadata: \n" +
                        "   Reader:  " + reader + "\n" +
                        "   Results: " + rawProperties);
            }
            return rawProperties;
        }
        finally
        {
            if (is != null)
            {
                try { is.close(); } catch (IOException ignored) {}
            }
        }
   }
   

and the error being thrown is :-

05:06:29,650  INFO  [extensions.webscripts.ScriptProcessorRegistry] Registered script processor javascript for extension js
WARN : org.apache.myfaces.shared_impl.util.LocaleUtils - Locale name in faces-config.xml null or empty, setting locale to default locale : en_US
WARN : org.springframework.beans.GenericTypeAwarePropertyDescriptor - Invalid JavaBean property 'baseUrl' being accessed! Ambiguous write methods found next to actually used [public void org.alfresco.wcm.client.impl.WebScriptCallerImpl.setBaseUrl(java.net.URI)]: [public void org.alfresco.wcm.client.impl.WebScriptCallerImpl.setBaseUrl(java.lang.String) throws java.net.URISyntaxException]
05:06:38,365  INFO  [alfresco.util.OpenOfficeConnectionTester] The OpenOffice connection was re-established.
05:09:04,404  DEBUG [content.metadata.MetadataExtracterRegistry] Finding extractors for text/xml
05:09:05,217  DEBUG [metadata.xml.XPathMetadataExtracter]
Found metadata extracter to process XML document:
   Selector: DITARootElementNameContentWorkerSelector[ workers={bookmap=com.quark.alfresco.content.metadata.xml.XPathWithResolverMetadataExtracter@16a51ac9, map=com.quark.alfresco.content.metadata.xml.XPathWithResolverMetadataExtracter@16a51ac9, reference=com.quark.alfresco.content.metadata.xml.XPathWithResolverMetadataExtracter@16a51ac9}]
   Document: ContentAccessor[ contentUrl=store://2011/6/24/5/9/fb334ddb-4510-47cc-a86c-9672a6f7f45f.bin, mimetype=text/xml, size=401, encoding=null, locale=en_US]
05:09:05,217  DEBUG [content.metadata.AbstractMappingMetadataExtracter] Starting metadata extraction:
   reader: ContentAccessor[ contentUrl=store://2011/6/24/5/9/fb334ddb-4510-47cc-a86c-9672a6f7f45f.bin, mimetype=text/xml, size=401, encoding=null, locale=en_US]
   extracter: com.quark.alfresco.content.metadata.xml.XPathWithResolverMetadataExtracter@16a51ac9
05:09:05,920  DEBUG [content.metadata.AbstractMappingMetadataExtracter] Metadata extraction failed:
   Extracter: com.quark.alfresco.content.metadata.xml.XPathWithResolverMetadataExtracter@16a51ac9
   Content:   ContentAccessor[ contentUrl=store://2011/6/24/5/9/fb334ddb-4510-47cc-a86c-9672a6f7f45f.bin, mimetype=text/xml, size=401, encoding=null, locale=en_US]
   claimed mime type: text/xml
   detected mime type: application/xml
java.lang.ClassCastException: java.util.ArrayList cannot be cast to org.w3c.dom.NodeList
   at org.alfresco.repo.content.metadata.xml.XPathMetadataExtracter.getNodeSetValue(XPathMetadataExtracter.java:277)
   at org.alfresco.repo.content.metadata.xml.XPathMetadataExtracter.processDocument(XPathMetadataExtracter.java:250)
   at com.quark.alfresco.content.metadata.xml.XPathWithResolverMetadataExtracter.extractRaw(XPathWithResolverMetadataExtracter.java:40)

As you can see it's the java.lang.ClassCastException: java.util.ArrayList cannot be cast to org.w3c.dom.NodeList when the Alfresco class is trying to resolve the xpath expression

I have located the point in the Alfresco org.alfresco.repo.content.metadata.xml.XPathMetaDataExtracter.class where it fails.

private Serializable getNodeSetValue(Document document, XPathExpression xpathExpression)
    throws XPathExpressionException
   {
     NodeList nodeList = null;
    try
     {
       nodeList = (NodeList)xpathExpression.evaluate(document, XPathConstants.NODESET);
     }
     catch (XPathExpressionException e)
     {
       if (logger.isDebugEnabled())
       {
         logger.debug("Unable to evaluate expression and return a NODESET: " + xpathExpression);
       }
       throw e;
     }

I guess what i'm hoping is that there is a reference that needs to be updated. Any help here would be greatly appreciated.

Thanks,
T
1 REPLY 1

telomari
Champ in-the-making
Champ in-the-making
… might be useful to post the xpath being used (in file dita-extractor-context.xml)

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>

<beans>
    <bean id="MapExtractor"
        class="com.quark.alfresco.content.metadata.xml.XPathWithResolverMetadataExtracter"
        parent="baseMetadataExtracter" >
        <property name="mappingProperties">
            <bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
                <property name="properties">
                    <props>
                        <prop key="namespace.prefix.gf">http://quark.com/model/dita/1.0</prop>
                        <prop key="ditaID">gf:ditaID</prop>
                        <prop key="ditaTitle">gf:ditaTitle</prop>
                    </props>
                </property>
            </bean>
        </property>
        <property name="xpathMappingProperties">
            <bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
                <property name="properties">
                    <props>
                        <!–<prop key="namespace.prefix.gf">http://quark.com/model/dita/1.0</prop>–>
                        <prop key="ditaID">/*/@id</prop>
                        <prop key="ditaTitle">/bookmap/booktitle/mainbooktitle | /reference/title | /map/@title</prop>
                    </props>
                </property>
            </bean>
        </property>
        <property name="catalogResolver">
            <ref bean="ditaCatalogResolver" />
        </property>
    </bean>

    <bean
        id="selecter.XML"
        class="com.quark.alfresco.content.selector.DITARootElementNameContentWorkerSelector"
        init-method="init">
        <property name="workers">
            <map>
                <entry key="bookmap">
                    <ref bean="MapExtractor" />
                </entry>
                <entry key="map">
                    <ref bean="MapExtractor" />
                </entry>
                <entry key="reference">
                <ref bean="MapExtractor" />
                </entry>
            </map>
        </property>
        <property name="catalogResolver">
            <ref bean="ditaCatalogResolver" />
        </property>
    </bean>

    <bean
        id="extracter.xml.sample.XMLMetadataExtracter"
        class="org.alfresco.repo.content.metadata.xml.XmlMetadataExtracter"
        parent="baseMetadataExtracter">
        <property name="overwritePolicy">
            <value>EAGER</value>
        </property>
        <property name="selectors">
            <list>
                <ref bean="selecter.XML" />
            </list>
        </property>
    </bean>
</beans>

Thanks,
T.