1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 package complex.writer;
25 
26 import com.sun.star.uno.UnoRuntime;
27 import com.sun.star.uno.AnyConverter;
28 import com.sun.star.uno.XComponentContext;
29 import com.sun.star.lang.WrappedTargetException;
30 import com.sun.star.lang.WrappedTargetRuntimeException;
31 import com.sun.star.lang.EventObject;
32 import com.sun.star.lang.XMultiServiceFactory;
33 import com.sun.star.lang.XComponent;
34 import com.sun.star.lang.XServiceInfo;
35 import com.sun.star.beans.XPropertySet;
36 import com.sun.star.beans.PropertyValue;
37 import com.sun.star.beans.Pair;
38 import com.sun.star.util.XCloseable;
39 import com.sun.star.frame.XStorable;
40 import com.sun.star.document.DocumentEvent;
41 import com.sun.star.document.XDocumentEventBroadcaster;
42 import com.sun.star.document.XDocumentEventListener;
43 import com.sun.star.text.XTextDocument;
44 import org.openoffice.test.Argument;
45 import org.openoffice.test.OfficeConnection;
46 
47 import java.net.URI;
48 import java.util.List;
49 import java.util.ArrayList;
50 import java.io.File;
51 
52 import org.junit.After;
53 import org.junit.AfterClass;
54 import org.junit.Before;
55 import org.junit.BeforeClass;
56 import org.junit.Test;
57 import static org.junit.Assert.*;
58 
59 /**
60  * a small program to load documents from one directory (recursively)
61  * and store them in another, implemented as a complex test.
62  */
63 public class LoadSaveTest
64 {
65     private static final OfficeConnection connection = new OfficeConnection();
66 
67     private XMultiServiceFactory m_xMSF = null;
68     private XComponentContext m_xContext = null;
69     private XDocumentEventBroadcaster m_xGEB = null;
70     private String m_TmpDir = null;
71 
72     private static final String m_fileURL = "file://";
73     private String m_SourceDir;
74     private String m_TargetDir;
75 
76     // setup and close connections
77     @BeforeClass
setUpConnection()78     public static void setUpConnection()
79         throws Exception
80     {
81         connection.setUp();
82     }
83 
84     @AfterClass
tearDownConnection()85     public static void tearDownConnection()
86         throws InterruptedException, com.sun.star.uno.Exception
87     {
88         connection.tearDown();
89     }
90 
getMSF()91     private XMultiServiceFactory getMSF()
92     {
93         final XMultiServiceFactory xMSF1 = UnoRuntime.queryInterface(XMultiServiceFactory.class, connection.getComponentContext().getServiceManager());
94         return xMSF1;
95     }
96 
97     @Before
before()98     public void before() throws Exception
99     {
100         m_xMSF = getMSF();
101         XPropertySet xPropertySet = (XPropertySet)
102             UnoRuntime.queryInterface(XPropertySet.class, m_xMSF);
103         Object defaultCtx = xPropertySet.getPropertyValue("DefaultContext");
104         m_xContext = (XComponentContext)
105             UnoRuntime.queryInterface(XComponentContext.class, defaultCtx);
106         assertTrue("could not get component context.", m_xContext != null);
107         Object oGEB = m_xMSF.createInstance(
108                 "com.sun.star.frame.GlobalEventBroadcaster");
109         m_xGEB = (XDocumentEventBroadcaster)
110             UnoRuntime.queryInterface(XDocumentEventBroadcaster.class, oGEB);
111         assertTrue("could not get global event broadcaster.", m_xGEB != null);
112         m_TmpDir = util.utils.getOfficeTemp(m_xMSF);
113         m_SourceDir = Argument.get("tdoc");
114         m_TargetDir = new URI(m_TmpDir).getPath() + "/sw_LoadSaveTest";
115         System.out.println("tempdir: " + m_TmpDir);
116         System.out.println("sourcedir: " + m_SourceDir);
117         System.out.println("targetdir: " + m_TargetDir);
118     }
119 
120     /*
121     @After
122     public void after()
123     {
124     }
125     */
126 
127     @Test
testLoadStore()128     public void testLoadStore() throws Exception
129     {
130         Pair<List<String>, List<String>> dirsFiles =
131             getDirAndFileNames(m_SourceDir);
132         makeDirs(m_TargetDir, dirsFiles.First);
133         for (String fileName : dirsFiles.Second)
134         {
135             try {
136                 testDoc(fileName);
137             } catch (Exception e) {
138                 report(e);
139             }
140         }
141     }
142 
testDoc(String fileName)143     public void testDoc(String fileName) throws Exception
144     {
145         XComponent xDoc = null;
146         EventListener xListener = new EventListener();
147         try {
148             m_xGEB.addDocumentEventListener(xListener);
149 
150             System.out.println("Loading document: " + fileName + " ...");
151 
152             PropertyValue[] loadProps = new PropertyValue[1];
153             loadProps[0] = new PropertyValue();
154             loadProps[0].Name = "ReadOnly";
155             loadProps[0].Value = new Boolean(true);
156 
157             String sourceFile = m_fileURL + m_SourceDir + fileName;
158 
159             xDoc = util.DesktopTools.loadDoc(m_xMSF, sourceFile, loadProps);
160 
161             System.out.println("... done");
162 
163             {
164                 // apparently OnLayoutFinished is not sent for every doc???
165                 // 10 seconds is evidently not enough for large documents
166                 int time = 0;
167                 while (!xListener.IsLayoutFinished() && (time < 30000)) {
168                     Thread.sleep(100);
169                     time += 100;
170                 }
171                 if (time >= 30000) {
172                     System.out.println("timeout: no OnLayoutFinished received!");
173                 }
174             }
175 
176             System.out.println("Storing document: " + fileName + " ...");
177 
178             XStorable xStor = (XStorable) UnoRuntime.queryInterface(
179                         XStorable.class, xDoc);
180 
181             String targetFile = m_fileURL + m_TargetDir + fileName;
182 
183             xStor.storeToURL(targetFile, new PropertyValue[0]);
184 
185             System.out.println("... done");
186 
187         } finally {
188             if (xDoc != null) {
189                 util.DesktopTools.closeDoc(xDoc);
190             }
191             if (xListener != null) {
192                 m_xGEB.removeDocumentEventListener(xListener);
193             }
194         }
195     }
196 
197     class EventListener implements XDocumentEventListener
198     {
199         boolean m_isLayoutFinished = false;
IsLayoutFinished()200         boolean IsLayoutFinished() { return m_isLayoutFinished; }
documentEventOccured(DocumentEvent Event)201         public void documentEventOccured(DocumentEvent Event)
202         {
203 //            System.out.println("event: " + Event.EventName);
204             if ("OnLayoutFinished".equals(Event.EventName))
205             {
206                 // we only have one doc at any time, so no need to check
207                 m_isLayoutFinished = true;
208 //                System.out.println("received OnLayoutFinished");
209             }
210         }
disposing(EventObject Event)211         public void disposing(EventObject Event) { }
212     }
213 
report2(Exception e)214     void report2(Exception e)
215     {
216         if (e instanceof WrappedTargetException)
217         {
218             System.err.println("Cause:");
219             Exception cause = (Exception)
220                 (((WrappedTargetException)e).TargetException);
221             System.err.println(cause.toString());
222             report2(cause);
223         } else if (e instanceof WrappedTargetRuntimeException) {
224             System.err.println("Cause:");
225             Exception cause = (Exception)
226                 (((WrappedTargetRuntimeException)e).TargetException);
227             System.err.println(cause.toString());
228             report2(cause);
229         }
230     }
231 
report(Exception e)232     void report(Exception e) {
233         System.err.println("Exception occurred:");
234         System.err.println(e.toString());
235         e.printStackTrace(System.err);
236         report2(e);
237 //        failed();
238     }
239 
getDirAndFileNames(String dir)240     Pair<List<String>, List<String>> getDirAndFileNames(String dir)
241     {
242         List<String> dirs = new ArrayList<String>();
243         List<String> files = new ArrayList<String>();
244         File root = new File(dir);
245         getDirAndFileNames(root, "", dirs, files);
246         return new Pair<List<String>, List<String>>(dirs, files);
247     }
248 
getDirAndFileNames(File file, String relPath, List<String> dirs, List<String> files)249     void getDirAndFileNames(File file, String relPath,
250             List<String> dirs, List<String> files)
251     {
252         assertTrue("does not exist: " + relPath, file.exists());
253         if (file.isDirectory()) {
254             dirs.add(relPath);
255             File[] subfiles = file.listFiles();
256             for (File subfile : subfiles)
257             {
258                 String subfileName =
259                     relPath + File.separator + subfile.getName();
260                 getDirAndFileNames(subfile, subfileName, dirs, files);
261             }
262         }
263         else if (file.isFile()) {
264             if (file.getName().endsWith(".odt")) {
265                 files.add(relPath);
266             }
267         }
268     }
269 
makeDirs(String target, List<String> dirs)270     void makeDirs(String target, List<String> dirs) throws Exception
271     {
272         for (String dir : dirs) {
273             File f = new File(target + dir);
274             if (!f.exists()) {
275                 if (!f.mkdir()) {
276                     throw new Exception("cannot mkdir: " + target + dir);
277                 }
278             }
279         }
280     }
281 }
282 
283