You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jetspeed-dev@portals.apache.org by wo...@apache.org on 2007/08/21 15:04:08 UTC

svn commit: r568113 - in /portals/jetspeed-2/branches/JETSPEED-2.1.3/components/page-manager/src: java/org/apache/jetspeed/page/document/psml/ test/org/apache/jetspeed/page/ test/org/apache/jetspeed/page/document/ test/org/apache/jetspeed/page/document...

Author: woonsan
Date: Tue Aug 21 06:04:07 2007
New Revision: 568113

URL: http://svn.apache.org/viewvc?rev=568113&view=rev
Log:
1. TestCastorXmlPageManager test case always fails because it transforms UTF-8 encoded psmls to ANSI encoded psmls by an xsl page during the setUp stage.
 - This problem was caused by o.a.j.page.DirectoryXMLTransform.java. It should use FileOutputStream for a StreamResult instead of FileWriter.

2. If we do load tests with many concurrent users (e.g. 200+ users), th e following exception occurs:
  "Could not unmarshal the file /home7/xep/Jetspeed-2.1.2/webapps/jetspeed/WEB-INF/pages/folder.metadata
FWK005 parse may not be called while parsing."
 - This problem was caused by o.a.j.page.document.psml.CastorFileSystemDocumentHandler.java. The unmarshallDocument() method was not thread-safe because it uses xmlReader member variable. The SAX XMLReader must not be shared among concurrent threads.
 - However, this problem could not be found often because if a document is just cached then the unmarshalDocument() method would not be called. So, when there's no cache of documents and many concurrent users rush to the system, this problem can occur. The system used to just leave a log with stack traces, not giving complaints to users.
 - TestCastorFileSystemDocumentHandler.java is a unit test code for this.

Added:
    portals/jetspeed-2/branches/JETSPEED-2.1.3/components/page-manager/src/test/org/apache/jetspeed/page/document/
    portals/jetspeed-2/branches/JETSPEED-2.1.3/components/page-manager/src/test/org/apache/jetspeed/page/document/psml/
    portals/jetspeed-2/branches/JETSPEED-2.1.3/components/page-manager/src/test/org/apache/jetspeed/page/document/psml/TestCastorFileSystemDocumentHandler.java
Modified:
    portals/jetspeed-2/branches/JETSPEED-2.1.3/components/page-manager/src/java/org/apache/jetspeed/page/document/psml/CastorFileSystemDocumentHandler.java
    portals/jetspeed-2/branches/JETSPEED-2.1.3/components/page-manager/src/test/org/apache/jetspeed/page/DirectoryXMLTransform.java

Modified: portals/jetspeed-2/branches/JETSPEED-2.1.3/components/page-manager/src/java/org/apache/jetspeed/page/document/psml/CastorFileSystemDocumentHandler.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/branches/JETSPEED-2.1.3/components/page-manager/src/java/org/apache/jetspeed/page/document/psml/CastorFileSystemDocumentHandler.java?rev=568113&r1=568112&r2=568113&view=diff
==============================================================================
--- portals/jetspeed-2/branches/JETSPEED-2.1.3/components/page-manager/src/java/org/apache/jetspeed/page/document/psml/CastorFileSystemDocumentHandler.java (original)
+++ portals/jetspeed-2/branches/JETSPEED-2.1.3/components/page-manager/src/java/org/apache/jetspeed/page/document/psml/CastorFileSystemDocumentHandler.java Tue Aug 21 06:04:07 2007
@@ -401,114 +401,118 @@
             Unmarshaller unmarshaller = new Unmarshaller();
             unmarshaller.setResolver((XMLClassDescriptorResolver) classDescriptorResolver);            
             unmarshaller.setValidation(false); // results in better performance
-            document = (Document) unmarshaller.unmarshal(new SAX2EventProducer()
-                {
-                    public void setContentHandler(final ContentHandler handler)
+            
+            synchronized (xmlReader)
+            {
+                document = (Document) unmarshaller.unmarshal(new SAX2EventProducer()
                     {
-                    	xmlReader.setContentHandler(new ContentHandler()
-                            {
-                                private int menuDepth = 0;
-
-                                public void characters(char[] ch, int start, int length) throws SAXException
-                                {
-                                    handler.characters(ch, start, length);
-                                }
-
-                                public void endDocument() throws SAXException
+                        public void setContentHandler(final ContentHandler handler)
+                        {
+                        	xmlReader.setContentHandler(new ContentHandler()
                                 {
-                                    handler.endDocument();
-                                }
+                                    private int menuDepth = 0;
 
-                                public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
-                                {
-                                    handler.ignorableWhitespace(ch, start, length);
-                                }
+                                    public void characters(char[] ch, int start, int length) throws SAXException
+                                    {
+                                        handler.characters(ch, start, length);
+                                    }
 
-                                public void processingInstruction(String target, String data) throws SAXException
-                                {
-                                    handler.processingInstruction(target, data);
-                                }
+                                    public void endDocument() throws SAXException
+                                    {
+                                        handler.endDocument();
+                                    }
 
-                                public void setDocumentLocator(Locator locator)
-                                {
-                                    handler.setDocumentLocator(locator);
-                                }
+                                    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
+                                    {
+                                        handler.ignorableWhitespace(ch, start, length);
+                                    }
 
-                                public void startDocument() throws SAXException
-                                {
-                                    handler.startDocument();
-                                }
+                                    public void processingInstruction(String target, String data) throws SAXException
+                                    {
+                                        handler.processingInstruction(target, data);
+                                    }
 
-								public void endElement(String uri, String localName, String qName) throws SAXException {
-                                    // always include all elements
-                                    handler.endElement(uri,localName,qName);
-                                    // track menu depth and insert menu-element nodes
-                                    // to encapsulate menu elements to support collection
-                                    // polymorphism in Castor
-                                    if (qName.equals("menu"))
+                                    public void setDocumentLocator(Locator locator)
                                     {
-                                        menuDepth--;
-                                        if (menuDepth > 0)
-                                        {
-                                            handler.endElement(null,null,"menu-element");
-                                        }
+                                        handler.setDocumentLocator(locator);
                                     }
-                                    else if ((menuDepth > 0) &&
-                                             (qName.equals("options") || qName.equals("separator") ||
-                                            		 qName.equals("include") || qName.equals("exclude")))
+
+                                    public void startDocument() throws SAXException
                                     {
-                                        handler.endElement(null,null,"menu-element");
+                                        handler.startDocument();
                                     }
-								}
 
-								public void endPrefixMapping(String prefix) throws SAXException {
-								}
+    								public void endElement(String uri, String localName, String qName) throws SAXException {
+                                        // always include all elements
+                                        handler.endElement(uri,localName,qName);
+                                        // track menu depth and insert menu-element nodes
+                                        // to encapsulate menu elements to support collection
+                                        // polymorphism in Castor
+                                        if (qName.equals("menu"))
+                                        {
+                                            menuDepth--;
+                                            if (menuDepth > 0)
+                                            {
+                                                handler.endElement(null,null,"menu-element");
+                                            }
+                                        }
+                                        else if ((menuDepth > 0) &&
+                                                 (qName.equals("options") || qName.equals("separator") ||
+                                                		 qName.equals("include") || qName.equals("exclude")))
+                                        {
+                                            handler.endElement(null,null,"menu-element");
+                                        }
+    								}
 
-								public void skippedEntity(String name) throws SAXException {
-									handler.skippedEntity(name);
-								}
+    								public void endPrefixMapping(String prefix) throws SAXException {
+    								}
 
-								public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
-                                    // track menu depth and insert menu-element nodes
-                                    // to encapsulate menu elements to support collection
-                                    // polymorphism in Castor
-									
-									if (qName.equals("menu"))
-                                    {
-                                        if (menuDepth > 0)
+    								public void skippedEntity(String name) throws SAXException {
+    									handler.skippedEntity(name);
+    								}
+
+    								public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
+                                        // track menu depth and insert menu-element nodes
+                                        // to encapsulate menu elements to support collection
+                                        // polymorphism in Castor
+    									
+    									if (qName.equals("menu"))
+                                        {
+                                            if (menuDepth > 0)
+                                            {
+                                                handler.startElement(null,null,"menu-element", null);
+                                            }
+                                            menuDepth++;
+                                        }
+                                        else if ((menuDepth > 0) &&
+                                                 (qName.equals("options") || qName.equals("separator") ||
+                                                  qName.equals("include") || qName.equals("exclude")))
                                         {
                                             handler.startElement(null,null,"menu-element", null);
                                         }
-                                        menuDepth++;
-                                    }
-                                    else if ((menuDepth > 0) &&
-                                             (qName.equals("options") || qName.equals("separator") ||
-                                              qName.equals("include") || qName.equals("exclude")))
-                                    {
-                                        handler.startElement(null,null,"menu-element", null);
-                                    }
 
-                                    // always include all elements
-                                    handler.startElement(null,null, qName, atts);
-								}
-
-								public void startPrefixMapping(String prefix, String uri) throws SAXException {
-								}
-                            });
-                    }
-                    public void start() throws SAXException
-                    {
-                        try
-                        {
-                        	xmlReader.parse(readerInput);
+                                        // always include all elements
+                                        handler.startElement(null,null, qName, atts);
+    								}
+
+    								public void startPrefixMapping(String prefix, String uri) throws SAXException {
+    								}
+                                });
                         }
-                        catch (IOException ioe)
+                        public void start() throws SAXException
                         {
-                            throw new SAXException(ioe);
+                            try
+                            {
+                            	xmlReader.parse(readerInput);
+                            }
+                            catch (IOException ioe)
+                            {
+                                throw new SAXException(ioe);
+                            }
                         }
-                    }
-                });
-
+                    });
+            }
+            
             document.setPath(path);
             AbstractBaseElement documentImpl = (AbstractBaseElement)document;
             documentImpl.setHandlerFactory(handlerFactory);

Modified: portals/jetspeed-2/branches/JETSPEED-2.1.3/components/page-manager/src/test/org/apache/jetspeed/page/DirectoryXMLTransform.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/branches/JETSPEED-2.1.3/components/page-manager/src/test/org/apache/jetspeed/page/DirectoryXMLTransform.java?rev=568113&r1=568112&r2=568113&view=diff
==============================================================================
--- portals/jetspeed-2/branches/JETSPEED-2.1.3/components/page-manager/src/test/org/apache/jetspeed/page/DirectoryXMLTransform.java (original)
+++ portals/jetspeed-2/branches/JETSPEED-2.1.3/components/page-manager/src/test/org/apache/jetspeed/page/DirectoryXMLTransform.java Tue Aug 21 06:04:07 2007
@@ -21,7 +21,6 @@
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
-import java.io.FileWriter;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.Writer;
@@ -158,7 +157,7 @@
                     
                     Transformer transformer = getXSLTForFile(child);
                     if (transformer != null){
-                        FileWriter f_out = new FileWriter(toFile);
+                        FileOutputStream f_out = new FileOutputStream(toFile);
                         try{
                             transformer.transform(new StreamSource(child), new StreamResult(f_out));
                             f_out.flush();

Added: portals/jetspeed-2/branches/JETSPEED-2.1.3/components/page-manager/src/test/org/apache/jetspeed/page/document/psml/TestCastorFileSystemDocumentHandler.java
URL: http://svn.apache.org/viewvc/portals/jetspeed-2/branches/JETSPEED-2.1.3/components/page-manager/src/test/org/apache/jetspeed/page/document/psml/TestCastorFileSystemDocumentHandler.java?rev=568113&view=auto
==============================================================================
--- portals/jetspeed-2/branches/JETSPEED-2.1.3/components/page-manager/src/test/org/apache/jetspeed/page/document/psml/TestCastorFileSystemDocumentHandler.java (added)
+++ portals/jetspeed-2/branches/JETSPEED-2.1.3/components/page-manager/src/test/org/apache/jetspeed/page/document/psml/TestCastorFileSystemDocumentHandler.java Tue Aug 21 06:04:07 2007
@@ -0,0 +1,168 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jetspeed.page.document.psml;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.jetspeed.om.page.Document;
+import org.apache.jetspeed.om.folder.psml.FolderMetaDataImpl;
+import org.apache.jetspeed.page.psml.CastorXmlPageManager;
+import org.apache.jetspeed.page.document.DocumentHandlerFactory;
+import org.apache.jetspeed.page.document.psml.DocumentHandlerFactoryImpl;
+import org.apache.jetspeed.cache.file.FileCache;
+
+/**
+ * <p>
+ * TestCastorFileSystemDocumentHandler
+ * </p>
+ * <p>
+ * 
+ * </p>
+ * 
+ * @author <a href="mailto:woonsan@apache.org">Woonsan Ko</a>
+ * @version $Id$
+ *  
+ */
+public class TestCastorFileSystemDocumentHandler extends TestCase
+{
+
+    protected CastorFileSystemDocumentHandler folderMetaDataDocumentHandler;
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see junit.framework.TestCase#setUp()
+     */
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+        
+        folderMetaDataDocumentHandler = new CastorFileSystemDocumentHandler(
+            "/JETSPEED-INF/castor/page-mapping.xml",
+            "folder.metadata",
+            FolderMetaDataImpl.class,
+            "testdata/pages",
+            new FileCache());
+            
+        Map handlerMap = new HashMap();
+        handlerMap.put("folder.metadata", folderMetaDataDocumentHandler);
+        DocumentHandlerFactory handlerFactory = new DocumentHandlerFactoryImpl(handlerMap);
+        folderMetaDataDocumentHandler.setHandlerFactory(handlerFactory);
+    }
+
+    /**
+     * <p>
+     * tearDown
+     * </p>
+     * 
+     * @see junit.framework.TestCase#tearDown()
+     * @throws java.lang.Exception
+     */
+    protected void tearDown() throws Exception
+    {
+        super.tearDown();
+    }
+
+    /**
+     * Defines the testcase name for JUnit.
+     * 
+     * @param name
+     *            the testcase's name.
+     */
+    public TestCastorFileSystemDocumentHandler( String name )
+    {
+        super(name);
+    }
+
+    /**
+     * Start the tests.
+     * 
+     * @param args
+     *            the arguments. Not used
+     */
+    public static void main( String args[] )
+    {
+        junit.awtui.TestRunner.main(new String[]{TestCastorFileSystemDocumentHandler.class.getName()});
+    }
+
+    /**
+     * Creates the test suite.
+     * 
+     * @return a test suite (<code>TestSuite</code>) that includes all
+     *         methods starting with "test"
+     */
+    public static Test suite()
+    {
+        // All methods starting with "test" will be executed in the test suite.
+        return new TestSuite(TestCastorFileSystemDocumentHandler.class);
+    }
+    
+    public void testFolderMetaData() throws Exception
+    {
+        Document doc = folderMetaDataDocumentHandler.getDocument("/folder1/folder.metadata", false);
+        assertNotNull(doc);
+        String title = doc.getTitle();
+        assertEquals("Default Title for Folder 1", title);
+    }
+
+    public void testFolderMetaDataInParallel() throws Exception
+    {
+        Thread [] threads = new Thread[10];
+        int i;
+        final List exceptions = new ArrayList(10);
+        
+        for (i = 0; i < threads.length; i++)
+        {
+            threads[i] = new Thread(new Runnable()
+                {
+                    public void run()
+                    {
+                        try
+                        {
+                            Document doc = folderMetaDataDocumentHandler.getDocument("/folder1/folder.metadata", false);
+                        }
+                        catch (Exception e)
+                        {
+                            e.printStackTrace(System.out);
+                            exceptions.add(e);
+                        }
+                    }
+                });
+        }
+        
+        for (i = 0; i < threads.length; i++)
+        {
+            threads[i].start();
+        }
+        
+        for (i = 0; i < threads.length; i++)
+        {
+            threads[i].join();
+        }
+        
+        assertTrue("folderMetaDataDocumentHandler.getDocument() is not thread-safe!", exceptions.size() == 0);
+    }
+
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: jetspeed-dev-unsubscribe@portals.apache.org
For additional commands, e-mail: jetspeed-dev-help@portals.apache.org