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 integration.forms; 25 26 import com.sun.star.beans.PropertyValue; 27 import com.sun.star.beans.XPropertySet; 28 import com.sun.star.form.binding.IncompatibleTypesException; 29 import com.sun.star.form.binding.XBindableValue; 30 import com.sun.star.form.binding.XValueBinding; 31 import com.sun.star.frame.XStorable; 32 import com.sun.star.io.IOException; 33 import com.sun.star.lang.XMultiServiceFactory; 34 import com.sun.star.uno.UnoRuntime; 35 import com.sun.star.util.CloseVetoException; 36 import com.sun.star.util.XCloseable; 37 import com.sun.star.xml.dom.XNode; 38 import com.sun.star.xsd.DataTypeClass; 39 import java.io.File; 40 import org.openoffice.xforms.Instance; 41 import org.openoffice.xforms.Model; 42 import org.openoffice.xforms.XMLDocument; 43 44 import org.junit.After; 45 import org.junit.AfterClass; 46 import org.junit.Before; 47 import org.junit.BeforeClass; 48 import org.junit.Test; 49 import static org.junit.Assert.*; 50 import org.openoffice.test.OfficeConnection; 51 52 53 public class XMLFormSettings 54 { 55 private static final OfficeConnection officeConnection = new OfficeConnection(); 56 private XMultiServiceFactory m_orb; 57 private XMLDocument m_document; 58 private Model m_defaultModel; 59 private FormLayer m_formLayer; 60 private XPropertySet m_stringBinding; 61 private XPropertySet m_booleanBinding; 62 private XPropertySet m_dateBinding; 63 64 @BeforeClass beforeClass()65 public static void beforeClass() throws Exception 66 { 67 officeConnection.setUp(); 68 } 69 70 @AfterClass afterClass()71 public static void afterClass() throws Exception 72 { 73 officeConnection.tearDown(); 74 } 75 76 /** Creates a new instance of XMLFormSettings */ XMLFormSettings()77 public XMLFormSettings() 78 { 79 } 80 81 /* ------------------------------------------------------------------ */ 82 @Before before()83 public void before() throws java.lang.Exception 84 { 85 // create the document and assign related members 86 m_orb = UnoRuntime.queryInterface(XMultiServiceFactory.class, officeConnection.getComponentContext().getServiceManager()); 87 m_document = new XMLDocument( m_orb ); 88 m_formLayer = new FormLayer( m_document ); 89 90 // create a simple structure in the DOM tree: an element with two attributes 91 String[] modelNames = m_document.getXFormModelNames(); 92 m_defaultModel = m_document.getXFormModel( modelNames[0] ); 93 final Instance defaultInstance = m_defaultModel.getDefaultInstance(); 94 // remove the default root node 95 defaultInstance.removeNode( "instanceData" ); 96 // create test structures 97 XNode stringElement = defaultInstance.createElement( "stringElement" ); 98 XNode booleanAttrib = defaultInstance.createAttribute( stringElement, "booleanAttribute", "true" ); 99 XNode dateAttrib = defaultInstance.createAttribute( stringElement, "dateAttribute" ); 100 101 assertTrue( "booleanAttrib's parent is wrong", 102 UnoRuntime.areSame( stringElement, booleanAttrib.getParentNode() ) ); 103 assertTrue( "dateAttrib's parent is wrong", 104 UnoRuntime.areSame( stringElement, dateAttrib.getParentNode() ) ); 105 106 // also create bindings for the element and its attributes, of the proper type 107 m_stringBinding = m_defaultModel.createBindingForNode( stringElement, DataTypeClass.STRING ); 108 m_booleanBinding = m_defaultModel.createBindingForNode( booleanAttrib, DataTypeClass.BOOLEAN ); 109 m_dateBinding = m_defaultModel.createBindingForNode( dateAttrib, DataTypeClass.DATE ); 110 111 // TODO: set up the bindings so that the date bindings is relevant if and only if 112 // the boolean value is true 113 114 // store the document 115 File tempFile = File.createTempFile( "xmlforms", ".odt" ); 116 tempFile.deleteOnExit(); 117 String fileURL = tempFile.toURL().toExternalForm(); 118 XStorable store = (XStorable)UnoRuntime.queryInterface( XStorable.class, 119 m_document.getDocument() ); 120 store.storeAsURL( fileURL, new PropertyValue[] {} ); 121 assertTrue( "document still modified after saving it", !m_document.isModified() ); 122 } 123 124 /* ------------------------------------------------------------------ */ 125 @After after()126 public void after() throws com.sun.star.uno.Exception, java.lang.Exception 127 { 128 impl_closeDocument(); 129 } 130 131 /* ------------------------------------------------------------------ */ impl_closeDocument()132 private void impl_closeDocument() throws CloseVetoException 133 { 134 if ( m_document != null ) 135 { 136 XCloseable closeDoc = (XCloseable)UnoRuntime.queryInterface( XCloseable.class, 137 m_document.getDocument() ); 138 closeDoc.close( true ); 139 } 140 } 141 142 /* ------------------------------------------------------------------ */ impl_bind( XPropertySet _control, XPropertySet _binding )143 private static void impl_bind( XPropertySet _control, XPropertySet _binding ) throws IncompatibleTypesException 144 { 145 XBindableValue bindableControl = (XBindableValue)UnoRuntime.queryInterface( 146 XBindableValue.class, _control ); 147 XValueBinding binding = (XValueBinding)UnoRuntime.queryInterface( 148 XValueBinding.class, _binding ); 149 bindableControl.setValueBinding( binding ); 150 } 151 152 /* ------------------------------------------------------------------ */ 153 /** checks if master-detail relationships including multiple keys work 154 */ 155 @Test checkExternalData()156 public void checkExternalData() throws com.sun.star.uno.Exception, java.lang.Exception 157 { 158 // some controls 159 XPropertySet stringControl = m_formLayer.createLabeledControl( 160 "DatabaseTextField", "Task", 10, 10, 6 ); 161 impl_bind( stringControl, m_stringBinding ); 162 163 XPropertySet booleanControl = m_formLayer.createControlAndShape( 164 "DatabaseCheckBox", 35, 18, 25, 6 ); 165 booleanControl.setPropertyValue( "Label", "has due date" ); 166 impl_bind( booleanControl, m_booleanBinding ); 167 168 XPropertySet dateControl = m_formLayer.createControlAndShape( 169 "DatabaseDateField", 40, 26, 25, 6 ); 170 dateControl.setPropertyValue( "Dropdown", new Boolean( true ) ); 171 impl_bind( dateControl, m_dateBinding ); 172 173 m_document.getCurrentView( ).toggleFormDesignMode( ); 174 175 // ensure the model is set up as containing "document-internal" data 176 m_defaultModel.setIsDocumentInternalData( true ); 177 assertTrue( "setting up the document to contain 'internal data' failed", 178 m_defaultModel.getIsDocumentInternalData() ); 179 impl_storeDocument(); 180 181 // okay, here we go ... 182 // what this particular test is about is to check whether we can set up the model 183 // so that any changes to any controls bound to any data in this model actually marks 184 // the containing document as modified 185 m_formLayer.userTextInput( stringControl, "don't break this test" ); 186 assertTrue( "model data changed, but document is not modified", 187 m_document.isModified() ); 188 189 // TODO: do this with the other control/binding types, too 190 191 // no the other way round: set up the model to contain "document-external" data 192 m_defaultModel.setIsDocumentInternalData( false ); 193 assertTrue( "setting up the document to contain 'internal data' failed", 194 !m_defaultModel.getIsDocumentInternalData() ); 195 impl_storeDocument(); 196 197 // and check that now, changes in the controls / model data are not reflected in 198 // document's modified state 199 m_formLayer.userTextInput( stringControl, "(or any other test, that is)" ); 200 assertTrue( "model data changed, but document is modified", 201 !m_document.isModified() ); 202 203 // ................................................................. 204 // finally, check whether the flag survives loading and saving 205 Model internalDataModel = m_document.addXFormModel( "internalData" ); 206 internalDataModel.setIsDocumentInternalData( true ); 207 Model externalDataModel = m_document.addXFormModel( "externalData" ); 208 externalDataModel.setIsDocumentInternalData( false ); 209 210 impl_storeDocument(); 211 m_document.reload(); 212 213 internalDataModel = m_document.getXFormModel( "internalData" ); 214 externalDataModel = m_document.getXFormModel( "externalData" ); 215 216 assertTrue( "setting up a model to contain 'internal data' did not survive reloading", 217 internalDataModel.getIsDocumentInternalData() ); 218 assertTrue( "setting up a model to contain 'external data' did not survive reloading", 219 !externalDataModel.getIsDocumentInternalData() ); 220 } 221 222 /* ------------------------------------------------------------------ */ 223 /** stores our document 224 * @throws com.sun.star.io.IOException 225 */ impl_storeDocument()226 private void impl_storeDocument() throws IOException 227 { 228 XStorable store = (XStorable)UnoRuntime.queryInterface( XStorable.class, 229 m_document.getDocument() ); 230 store.store(); 231 assertTrue( "document still modified after saving it", !m_document.isModified() ); 232 } 233 } 234