1 /*************************************************************************
2 *
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
6 *
7 * OpenOffice.org - a multi-platform office productivity suite
8 *
9 * This file is part of OpenOffice.org.
10 *
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
14 *
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
20 *
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org.  If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
25 *
26 ************************************************************************/
27 
28 package complex.writer;
29 
30 import com.sun.star.lang.XMultiServiceFactory;
31 import com.sun.star.text.XTextDocument;
32 import com.sun.star.uno.UnoRuntime;
33 import org.junit.After;
34 import org.junit.AfterClass;
35 import org.junit.Before;
36 import org.junit.BeforeClass;
37 import org.junit.Test;
38 import org.openoffice.test.OfficeConnection;
39 import static org.junit.Assert.*;
40 
41 /**
42  *
43  * @author od138299
44  */
45 public class CheckCrossReferences {
46 
47     private com.sun.star.container.XEnumeration xParaEnum;
48     private com.sun.star.container.XEnumeration xPortionEnum;
49     private com.sun.star.util.XRefreshable xFldsRefresh;
50 
51     public com.sun.star.text.XTextField getNextField()
52         throws com.sun.star.uno.Exception
53     {
54         if ( xPortionEnum != null ) {
55             while ( xPortionEnum.hasMoreElements() ) {
56                 com.sun.star.beans.XPropertySet xPortionProps =
57                     (com.sun.star.beans.XPropertySet)UnoRuntime.queryInterface(
58                         com.sun.star.beans.XPropertySet.class , xPortionEnum.nextElement());
59                 final String sPortionType =
60                     xPortionProps.getPropertyValue( "TextPortionType" ).toString();
61                 if ( sPortionType.equals( "TextField") ) {
62                     com.sun.star.text.XTextField xField = (com.sun.star.text.XTextField)UnoRuntime.queryInterface(
63                         com.sun.star.text.XTextField.class,
64                         xPortionProps.getPropertyValue( "TextField" ) );
65                     assertNotNull("Cannot retrieve next field.", xField);
66                     return xField;
67                 }
68             }
69         }
70 
71         while ( xParaEnum.hasMoreElements() ) {
72             com.sun.star.container.XEnumerationAccess aPara =
73                 (com.sun.star.container.XEnumerationAccess)UnoRuntime.queryInterface(
74                     com.sun.star.container.XEnumerationAccess.class, xParaEnum.nextElement());
75             xPortionEnum = aPara.createEnumeration();
76             while ( xPortionEnum.hasMoreElements() ) {
77                 com.sun.star.beans.XPropertySet xPortionProps =
78                     (com.sun.star.beans.XPropertySet)UnoRuntime.queryInterface(
79                         com.sun.star.beans.XPropertySet.class , xPortionEnum.nextElement());
80                 final String sPortionType =
81                     xPortionProps.getPropertyValue( "TextPortionType" ).toString();
82                 if ( sPortionType.equals( "TextField") ) {
83                     com.sun.star.text.XTextField xField = (com.sun.star.text.XTextField)UnoRuntime.queryInterface(
84                         com.sun.star.text.XTextField.class,
85                         xPortionProps.getPropertyValue( "TextField" ) );
86                     assertNotNull("Cannot retrieve next field.", xField);
87                     return xField;
88                 }
89             }
90         }
91 
92         fail("Cannot retrieve next field.");
93         return null; // unreachable
94     }
95 
96     public com.sun.star.beans.XPropertySet getFieldProps(
97             com.sun.star.text.XTextField xField ) {
98         com.sun.star.beans.XPropertySet xProps =
99                 (com.sun.star.beans.XPropertySet)UnoRuntime.queryInterface(
100                 com.sun.star.beans.XPropertySet.class, xField );
101 
102         assertNotNull("Cannot retrieve field properties.", xProps);
103 
104         return xProps;
105     }
106 
107     public void checkField( com.sun.star.text.XTextField xField,
108             com.sun.star.beans.XPropertySet xProps,
109             short nFormat,
110             String aExpectedFldResult )
111         throws com.sun.star.uno.Exception
112     {
113         // set requested format
114         xProps.setPropertyValue("ReferenceFieldPart", new Short(nFormat));
115 
116         // refresh fields in order to get new format applied
117         xFldsRefresh.refresh();
118 
119         String aFldResult = xField.getPresentation( false );
120         assertEquals( "set reference field format doesn't result in correct field result",
121                       aExpectedFldResult, aFldResult);
122     }
123 
124     @Test public void checkCrossReferences() throws com.sun.star.uno.Exception {
125         // setup paragraph enumeration
126         {
127             com.sun.star.container.XEnumerationAccess xParaEnumAccess =
128                     (com.sun.star.container.XEnumerationAccess)UnoRuntime.queryInterface(
129                     com.sun.star.container.XEnumerationAccess.class, document.getText());
130             xParaEnum = xParaEnumAccess.createEnumeration();
131         }
132 
133         // get field refresher
134         {
135             com.sun.star.text.XTextFieldsSupplier xFieldSupp =
136                     (com.sun.star.text.XTextFieldsSupplier)UnoRuntime.queryInterface(
137                     com.sun.star.text.XTextFieldsSupplier.class, document);
138             xFldsRefresh = (com.sun.star.util.XRefreshable)UnoRuntime.queryInterface(
139                     com.sun.star.util.XRefreshable.class, xFieldSupp.getTextFields());
140         }
141 
142         // check first reference field
143         {
144             // strings for checking
145             final String FldResult1 = "*i*";
146             final String FldResult2 = "+b+*i*";
147             final String FldResult3 = "-1-+b+*i*";
148             final String FldResult4 = "1.";
149             final String FldResult5 = " 1.";
150             final String FldResult6 = "A. 1.";
151 
152             // variables for current field
153             com.sun.star.text.XTextField xField = null;
154             com.sun.star.beans.XPropertySet xProps = null;
155 
156             xField = getNextField();
157             xProps = getFieldProps( xField );
158             checkField( xField, xProps, com.sun.star.text.ReferenceFieldPart.NUMBER, FldResult2 );
159             checkField( xField, xProps, com.sun.star.text.ReferenceFieldPart.NUMBER_NO_CONTEXT, FldResult1 );
160             checkField( xField, xProps, com.sun.star.text.ReferenceFieldPart.NUMBER_FULL_CONTEXT, FldResult3 );
161 
162             xField = getNextField();
163             xProps = getFieldProps( xField );
164             checkField( xField, xProps, com.sun.star.text.ReferenceFieldPart.NUMBER, FldResult1 );
165             checkField( xField, xProps, com.sun.star.text.ReferenceFieldPart.NUMBER_NO_CONTEXT, FldResult1 );
166             checkField( xField, xProps, com.sun.star.text.ReferenceFieldPart.NUMBER_FULL_CONTEXT, FldResult3 );
167 
168             xField = getNextField();
169             xProps = getFieldProps( xField );
170             checkField( xField, xProps, com.sun.star.text.ReferenceFieldPart.NUMBER, FldResult3 );
171             checkField( xField, xProps, com.sun.star.text.ReferenceFieldPart.NUMBER_NO_CONTEXT, FldResult1 );
172             checkField( xField, xProps, com.sun.star.text.ReferenceFieldPart.NUMBER_FULL_CONTEXT, FldResult3 );
173 
174             xField = getNextField();
175             xProps = getFieldProps( xField );
176             checkField( xField, xProps, com.sun.star.text.ReferenceFieldPart.NUMBER, FldResult5 );
177             checkField( xField, xProps, com.sun.star.text.ReferenceFieldPart.NUMBER_NO_CONTEXT, FldResult4 );
178             checkField( xField, xProps, com.sun.star.text.ReferenceFieldPart.NUMBER_FULL_CONTEXT, FldResult6 );
179 
180             xField = getNextField();
181             xProps = getFieldProps( xField );
182             checkField( xField, xProps, com.sun.star.text.ReferenceFieldPart.NUMBER, FldResult4 );
183             checkField( xField, xProps, com.sun.star.text.ReferenceFieldPart.NUMBER_NO_CONTEXT, FldResult4 );
184             checkField( xField, xProps, com.sun.star.text.ReferenceFieldPart.NUMBER_FULL_CONTEXT, FldResult6 );
185 
186             xField = getNextField();
187             xProps = getFieldProps( xField );
188             checkField( xField, xProps, com.sun.star.text.ReferenceFieldPart.NUMBER, FldResult6 );
189             checkField( xField, xProps, com.sun.star.text.ReferenceFieldPart.NUMBER_NO_CONTEXT, FldResult4 );
190             checkField( xField, xProps, com.sun.star.text.ReferenceFieldPart.NUMBER_FULL_CONTEXT, FldResult6 );
191         }
192 
193         // insert a certain cross-reference bookmark and a reference field to this bookmark
194         {
195             // restart paragraph enumeration
196             com.sun.star.container.XEnumerationAccess xParaEnumAccess =
197                     (com.sun.star.container.XEnumerationAccess)UnoRuntime.queryInterface(
198                     com.sun.star.container.XEnumerationAccess.class, document.getText());
199             xParaEnum = xParaEnumAccess.createEnumeration();
200 
201             // iterate on the paragraphs to find certain paragraph to insert the bookmark
202             com.sun.star.text.XTextRange xParaTextRange = null;
203             while ( xParaEnum.hasMoreElements() ) {
204                 xParaTextRange = (com.sun.star.text.XTextRange)UnoRuntime.queryInterface(
205                     com.sun.star.text.XTextRange.class, xParaEnum.nextElement());
206                 if ( xParaTextRange.getString().equals( "J" ) ) {
207                     break;
208                 }
209                 else {
210                     xParaTextRange = null;
211                 }
212             }
213             assertNotNull(
214                 "Cannot find paragraph to insert cross-reference bookmark.",
215                 xParaTextRange);
216 
217             // insert bookmark
218             XMultiServiceFactory xFac = (XMultiServiceFactory)UnoRuntime.queryInterface(
219                     XMultiServiceFactory.class, document);
220             final String cBookmarkName = "__RefNumPara__47114711";
221             com.sun.star.text.XTextContent xBookmark =
222                 (com.sun.star.text.XTextContent)UnoRuntime.queryInterface(
223                     com.sun.star.text.XTextContent.class,
224                     xFac.createInstance( "com.sun.star.text.Bookmark" ) );
225             if ( xBookmark != null ) {
226                 com.sun.star.container.XNamed xName =
227                         (com.sun.star.container.XNamed)UnoRuntime.queryInterface(
228                         com.sun.star.container.XNamed.class, xBookmark );
229                 xName.setName( cBookmarkName );
230                 xBookmark.attach(xParaTextRange.getStart());
231             }
232 
233             // insert reference field, which references the inserted bookmark
234             com.sun.star.text.XTextContent xNewField =
235                 (com.sun.star.text.XTextContent)UnoRuntime.queryInterface(
236                     com.sun.star.text.XTextContent.class,
237                     xFac.createInstance( "com.sun.star.text.TextField.GetReference" ) );
238             if ( xNewField != null ) {
239                 com.sun.star.beans.XPropertySet xFieldProps =
240                         (com.sun.star.beans.XPropertySet)UnoRuntime.queryInterface(
241                         com.sun.star.beans.XPropertySet.class, xNewField );
242                 xFieldProps.setPropertyValue( "ReferenceFieldPart", new Short(com.sun.star.text.ReferenceFieldPart.TEXT) );
243                 xFieldProps.setPropertyValue( "ReferenceFieldSource", new Short(com.sun.star.text.ReferenceFieldSource.BOOKMARK) );
244                 xFieldProps.setPropertyValue( "SourceName", cBookmarkName );
245                 com.sun.star.text.XTextRange xFieldTextRange =
246                         (com.sun.star.text.XTextRange)UnoRuntime.queryInterface(
247                         com.sun.star.text.XTextRange.class, xParaEnum.nextElement());
248                 xNewField.attach(xFieldTextRange.getEnd());
249                 xFldsRefresh.refresh();
250             }
251 
252             // check inserted reference field
253             com.sun.star.text.XTextField xField =
254                     (com.sun.star.text.XTextField)UnoRuntime.queryInterface(
255                     com.sun.star.text.XTextField.class, xNewField );
256             assertEquals( "inserted reference field doesn't has correct field result",
257                           "J", xField.getPresentation( false ) );
258 
259             xParaTextRange.getStart().setString( "Hallo new bookmark: " );
260             xFldsRefresh.refresh();
261             assertEquals( "inserted reference field doesn't has correct field result",
262                           "Hallo new bookmark: J", xField.getPresentation( false ) );
263         }
264     }
265 
266     @Before public void setUpDocument() throws com.sun.star.uno.Exception {
267         document = util.WriterTools.loadTextDoc(
268             UnoRuntime.queryInterface(
269                 XMultiServiceFactory.class,
270                 connection.getComponentContext().getServiceManager()),
271             TestDocument.getUrl("CheckCrossReferences.odt"));
272     }
273 
274     @After public void tearDownDocument() {
275         util.DesktopTools.closeDoc(document);
276     }
277 
278     private XTextDocument document = null;
279 
280     @BeforeClass public static void setUpConnection() throws Exception {
281         connection.setUp();
282     }
283 
284     @AfterClass public static void tearDownConnection()
285         throws InterruptedException, com.sun.star.uno.Exception
286     {
287         connection.tearDown();
288     }
289 
290     private static final OfficeConnection connection = new OfficeConnection();
291 }
292