1 /*
2  * This file is part of the LibreOffice project.
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  *
8  * This file incorporates work covered by the following license notice:
9  *
10  *   Licensed to the Apache Software Foundation (ASF) under one or more
11  *   contributor license agreements. See the NOTICE file distributed
12  *   with this work for additional information regarding copyright
13  *   ownership. The ASF licenses this file to you under the Apache
14  *   License, Version 2.0 (the "License"); you may not use this file
15  *   except in compliance with the License. You may obtain a copy of
16  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
17  */
18 
19 package integration.forms;
20 
21 import com.sun.star.beans.PropertyValue;
22 import com.sun.star.beans.XPropertySet;
23 import com.sun.star.form.binding.IncompatibleTypesException;
24 import com.sun.star.form.binding.XBindableValue;
25 import com.sun.star.form.binding.XValueBinding;
26 import com.sun.star.frame.XStorable;
27 import com.sun.star.io.IOException;
28 import com.sun.star.lang.XMultiServiceFactory;
29 import com.sun.star.uno.UnoRuntime;
30 import com.sun.star.util.CloseVetoException;
31 import com.sun.star.util.XCloseable;
32 import com.sun.star.xml.dom.XNode;
33 import com.sun.star.xsd.DataTypeClass;
34 import java.io.File;
35 import org.openoffice.xforms.Instance;
36 import org.openoffice.xforms.Model;
37 import org.openoffice.xforms.XMLDocument;
38 
39 public class XMLFormSettings extends complexlib.ComplexTestCase
40 {
41     private XMLDocument             m_document;
42     private Model                   m_defaultModel;
43     private FormLayer               m_formLayer;
44     private XPropertySet            m_stringBinding;
45     private XPropertySet            m_booleanBinding;
46     private XPropertySet            m_dateBinding;
47 
48     /* ------------------------------------------------------------------ */
49     @Override
getTestMethodNames()50     public String[] getTestMethodNames()
51     {
52         return new String[] {
53             "checkExternalData"
54         };
55     }
56 
57     /* ------------------------------------------------------------------ */
58     @Override
getTestObjectName()59     public String getTestObjectName()
60     {
61         return "Form Control Spreadsheet Cell Binding Test";
62     }
63 
64     /* ------------------------------------------------------------------ */
before()65     public void before() throws java.lang.Exception
66     {
67         // create the document and assign related members
68         XMultiServiceFactory orb = param.getMSF();
69         m_document = new XMLDocument( orb );
70         m_formLayer = new FormLayer( m_document );
71 
72         // create a simple structure in the DOM tree: an element with two attributes
73         String[] modelNames = m_document.getXFormModelNames();
74         m_defaultModel = m_document.getXFormModel( modelNames[0] );
75         final Instance defaultInstance = m_defaultModel.getDefaultInstance();
76         // remove the default root node
77         defaultInstance.removeNode( "instanceData" );
78         // create test structures
79         XNode stringElement = defaultInstance.createElement( "stringElement" );
80         XNode booleanAttrib = defaultInstance.createAttribute( stringElement, "booleanAttribute", "true" );
81         XNode dateAttrib = defaultInstance.createAttribute( stringElement, "dateAttribute" );
82 
83         assure( "booleanAttrib's parent is wrong",
84             UnoRuntime.areSame( stringElement, booleanAttrib.getParentNode() ) );
85         assure( "dateAttrib's parent is wrong",
86             UnoRuntime.areSame( stringElement, dateAttrib.getParentNode() ) );
87 
88         // also create bindings for the element and its attributes, of the proper type
89         m_stringBinding = m_defaultModel.createBindingForNode( stringElement, DataTypeClass.STRING );
90         m_booleanBinding = m_defaultModel.createBindingForNode( booleanAttrib, DataTypeClass.BOOLEAN );
91         m_dateBinding = m_defaultModel.createBindingForNode( dateAttrib, DataTypeClass.DATE );
92 
93         // TODO: set up the bindings so that the date bindings is relevant if and only if
94         // the boolean value is true
95 
96         // store the document
97         File tempFile = File.createTempFile( "xmlforms", ".odt" );
98         tempFile.deleteOnExit();
99         String fileURL = tempFile.toURI().toURL().toExternalForm();
100         XStorable store = UnoRuntime.queryInterface( XStorable.class,
101             m_document.getDocument() );
102         store.storeAsURL( fileURL, new PropertyValue[] {} );
103         assure( "document still modified after saving it", !m_document.isModified() );
104     }
105 
106     /* ------------------------------------------------------------------ */
after()107     public void after() throws com.sun.star.uno.Exception, java.lang.Exception
108     {
109         impl_closeDocument();
110     }
111 
112     /* ------------------------------------------------------------------ */
impl_closeDocument()113     private void impl_closeDocument() throws CloseVetoException
114     {
115         if ( m_document != null )
116         {
117             XCloseable closeDoc = UnoRuntime.queryInterface( XCloseable.class,
118                 m_document.getDocument() );
119             closeDoc.close( true );
120         }
121     }
122 
123     /* ------------------------------------------------------------------ */
impl_bind( XPropertySet _control, XPropertySet _binding )124     private static void impl_bind( XPropertySet _control, XPropertySet _binding ) throws IncompatibleTypesException
125     {
126         XBindableValue bindableControl = UnoRuntime.queryInterface(
127             XBindableValue.class, _control );
128         XValueBinding binding = UnoRuntime.queryInterface(
129             XValueBinding.class, _binding );
130         bindableControl.setValueBinding( binding );
131     }
132 
133     /* ------------------------------------------------------------------ */
134     /** checks if master-detail relationships including multiple keys work
135      */
checkExternalData()136     public void checkExternalData() throws com.sun.star.uno.Exception, java.lang.Exception
137     {
138         // some controls
139         XPropertySet stringControl = m_formLayer.createLabeledControl(
140             "DatabaseTextField", "Task", 10, 10, 6 );
141         impl_bind( stringControl, m_stringBinding );
142 
143         XPropertySet booleanControl = m_formLayer.createControlAndShape(
144             "DatabaseCheckBox", 35, 18, 25, 6 );
145         booleanControl.setPropertyValue( "Label", "has due date" );
146         impl_bind( booleanControl, m_booleanBinding );
147 
148         XPropertySet dateControl = m_formLayer.createControlAndShape(
149             "DatabaseDateField", 40, 26, 25, 6 );
150         dateControl.setPropertyValue( "Dropdown", Boolean.TRUE );
151         impl_bind( dateControl, m_dateBinding );
152 
153         m_document.getCurrentView( ).toggleFormDesignMode( );
154 
155         // ensure the model is set up as containing "document-internal" data
156         m_defaultModel.setIsDocumentInternalData( true );
157         assure( "setting up the document to contain 'internal data' failed",
158             m_defaultModel.getIsDocumentInternalData() );
159         impl_storeDocument();
160 
161         // okay, here we go ...
162         // what this particular test is about is to check whether we can set up the model
163         // so that any changes to any controls bound to any data in this model actually marks
164         // the containing document as modified
165         m_formLayer.userTextInput( stringControl, "don't break this test" );
166         assure( "model data changed, but document is not modified",
167             m_document.isModified() );
168 
169         // TODO: do this with the other control/binding types, too
170 
171         // no the other way round: set up the model to contain "document-external" data
172         m_defaultModel.setIsDocumentInternalData( false );
173         assure( "setting up the document to contain 'internal data' failed",
174             !m_defaultModel.getIsDocumentInternalData() );
175         impl_storeDocument();
176 
177         // and check that now, changes in the controls / model data are not reflected in
178         // document's modified state
179         m_formLayer.userTextInput( stringControl, "(or any other test, that is)" );
180         assure( "model data changed, but document is modified",
181             !m_document.isModified() );
182 
183 
184         // finally, check whether the flag survives loading and saving
185         Model internalDataModel = m_document.addXFormModel( "internalData" );
186         internalDataModel.setIsDocumentInternalData( true );
187         Model externalDataModel = m_document.addXFormModel( "externalData" );
188         externalDataModel.setIsDocumentInternalData( false );
189 
190         impl_storeDocument();
191         m_document.reload();
192 
193         internalDataModel = m_document.getXFormModel( "internalData" );
194         externalDataModel = m_document.getXFormModel( "externalData" );
195 
196         assure( "setting up a model to contain 'internal data' did not survive reloading",
197             internalDataModel.getIsDocumentInternalData() );
198         assure( "setting up a model to contain 'external data' did not survive reloading",
199             !externalDataModel.getIsDocumentInternalData() );
200     }
201 
202     /* ------------------------------------------------------------------ */
203     /** stores our document
204      * @throws com.sun.star.io.IOException
205      */
impl_storeDocument()206     private void impl_storeDocument() throws IOException
207     {
208         XStorable store = UnoRuntime.queryInterface( XStorable.class,
209             m_document.getDocument() );
210         store.store();
211         assure( "document still modified after saving it", !m_document.isModified() );
212     }
213 }
214