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 package integration.forms; 24 25 import com.sun.star.beans.PropertyAttribute; 26 import com.sun.star.beans.PropertyChangeEvent; 27 import com.sun.star.beans.PropertyExistException; 28 import com.sun.star.beans.PropertyValue; 29 import com.sun.star.beans.PropertyVetoException; 30 import com.sun.star.beans.UnknownPropertyException; 31 import com.sun.star.beans.XPropertyChangeListener; 32 import com.sun.star.beans.XPropertyContainer; 33 import com.sun.star.beans.XPropertySet; 34 import com.sun.star.beans.XPropertySetInfo; 35 import com.sun.star.frame.XStorable; 36 import com.sun.star.lang.EventObject; 37 import com.sun.star.uno.UnoRuntime; 38 39 import com.sun.star.lang.XMultiServiceFactory; 40 41 import com.sun.star.util.XCloseable; 42 43 import org.junit.After; 44 import org.junit.AfterClass; 45 import org.junit.Before; 46 import org.junit.BeforeClass; 47 import org.junit.Test; 48 import static org.junit.Assert.*; 49 import org.openoffice.test.OfficeConnection; 50 51 52 public class FormPropertyBags implements XPropertyChangeListener 53 { 54 private static final OfficeConnection officeConnection = new OfficeConnection(); 55 private DocumentHelper m_document; 56 private FormLayer m_formLayer; 57 private XMultiServiceFactory m_orb; 58 59 private PropertyChangeEvent m_propertyChangeEvent; 60 61 @BeforeClass beforeClass()62 public static void beforeClass() throws Exception 63 { 64 officeConnection.setUp(); 65 } 66 67 @AfterClass afterClass()68 public static void afterClass() throws Exception 69 { 70 officeConnection.tearDown(); 71 } 72 73 /** Creates a new instance of FormPropertyBags */ FormPropertyBags()74 public FormPropertyBags() 75 { 76 m_propertyChangeEvent = new PropertyChangeEvent(); 77 } 78 79 /* ------------------------------------------------------------------ */ 80 @Before before()81 public void before() throws com.sun.star.uno.Exception, java.lang.Exception 82 { 83 m_orb = UnoRuntime.queryInterface(XMultiServiceFactory.class, officeConnection.getComponentContext().getServiceManager()); 84 m_document = DocumentHelper.blankTextDocument( m_orb ); 85 m_formLayer = new FormLayer( m_document ); 86 } 87 88 /* ------------------------------------------------------------------ */ impl_closeDoc()89 private void impl_closeDoc() throws com.sun.star.uno.Exception 90 { 91 if ( m_document != null ) 92 { 93 XCloseable closeDoc = UnoRuntime.queryInterface( XCloseable.class, m_document.getDocument() ); 94 closeDoc.close( true ); 95 } 96 } 97 98 /* ------------------------------------------------------------------ */ 99 @After after()100 public void after() throws com.sun.star.uno.Exception, java.lang.Exception 101 { 102 impl_closeDoc(); 103 } 104 105 /* ------------------------------------------------------------------ */ 106 @Test checkSomething()107 public void checkSomething() throws com.sun.star.uno.Exception, java.lang.Exception 108 { 109 XPropertySet textFieldModel = m_formLayer.createControlAndShape( "DatabaseTextField", 10, 10, 25, 6 ); 110 111 // check whether adding new properties is successful 112 XPropertyContainer propContainer = UnoRuntime.queryInterface( 113 XPropertyContainer.class, textFieldModel ); 114 assertTrue("XPropertyContainer not supported!", propContainer != null ); 115 116 propContainer.addProperty( "SomeBoundText", PropertyAttribute.BOUND, "InitialBoundText" ); 117 propContainer.addProperty( "SomeTransientText", PropertyAttribute.TRANSIENT, "InitialTransientProperty" ); 118 propContainer.addProperty( "SomeReadonlyText", PropertyAttribute.READONLY, "InitialReadonlyText" ); 119 propContainer.addProperty( "SomeNumericValue", PropertyAttribute.BOUND, new Integer( 42 ) ); 120 121 XPropertySetInfo propertyInfo = textFieldModel.getPropertySetInfo(); 122 assertTrue( "Per service definition, dynamic properties are expected to be forced to be removeable", 123 ( propertyInfo.getPropertyByName("SomeBoundText").Attributes & PropertyAttribute.REMOVEABLE ) != 0 ); 124 125 // a second addition of a property with an existent name should be rejected 126 boolean caughtExpected = false; 127 try { propContainer.addProperty( "SomeBoundText", PropertyAttribute.BOUND, "InitialBoundText" ); } 128 catch( PropertyExistException e ) { caughtExpected = true; } 129 catch( Exception e ) { } 130 assertTrue( "repeated additions of a property with the same name should be rejected", 131 caughtExpected ); 132 133 // check whether the properties are bound as expected 134 impl_checkPropertyValueNotification( textFieldModel ); 135 136 // check property value persistence 137 impl_checkPropertyPersistence(); 138 } 139 140 /* ------------------------------------------------------------------ */ impl_checkPropertyValueNotification( XPropertySet _controlModel )141 private void impl_checkPropertyValueNotification( XPropertySet _controlModel ) throws com.sun.star.uno.Exception 142 { 143 _controlModel.addPropertyChangeListener( "", this ); 144 145 _controlModel.setPropertyValue( "SomeBoundText", "ChangedBoundText" ); 146 assertTrue( "changes in the bound property are not properly notified", 147 m_propertyChangeEvent.PropertyName.equals( "SomeBoundText" ) 148 && m_propertyChangeEvent.OldValue.equals( "InitialBoundText" ) 149 && m_propertyChangeEvent.NewValue.equals( "ChangedBoundText" ) ); 150 151 m_propertyChangeEvent = null; 152 _controlModel.setPropertyValue( "SomeTransientText", "ChangedTransientText" ); 153 assertTrue( "changes in non-bound properties should not be notified", 154 m_propertyChangeEvent == null ); 155 156 boolean caughtExpected = false; 157 try { _controlModel.setPropertyValue( "SomeReadonlyText", "ChangedReadonlyText" ); } 158 catch( PropertyVetoException e ) { caughtExpected = true; } 159 catch( Exception e ) { } 160 assertTrue( "trying to write a read-only property did not give the expected result", 161 caughtExpected ); 162 163 _controlModel.removePropertyChangeListener( "", this ); 164 } 165 166 /* ------------------------------------------------------------------ */ impl_checkPropertyPersistence()167 private void impl_checkPropertyPersistence() throws com.sun.star.uno.Exception 168 { 169 // store the document 170 XStorable store = UnoRuntime.queryInterface( XStorable.class, m_document.getDocument() ); 171 String documentURL = util.utils.getOfficeTemp( m_orb ) + "document.odt"; 172 PropertyValue[] storeArguments = new PropertyValue[] { new PropertyValue() }; 173 storeArguments[0].Name = "FilterName"; 174 storeArguments[0].Value = "writer8"; 175 store.storeAsURL( documentURL, storeArguments ); 176 177 // close and re-load it 178 impl_closeDoc(); 179 180 m_document = DocumentHelper.loadDocument( m_orb, documentURL ); 181 m_formLayer = new FormLayer( m_document ); 182 183 XPropertySet textFieldModel = m_formLayer.getControlModel( new int[] { 0, 0 } ); 184 185 // all persistent properties should have the expected values 186 assertTrue( "persistent properties did not survive reload (1)!", ((String)textFieldModel.getPropertyValue( "SomeBoundText" )).equals( "ChangedBoundText" ) ); 187 assertTrue( "persistent properties did not survive reload (2)!", ((String)textFieldModel.getPropertyValue( "SomeReadonlyText" )).equals( "InitialReadonlyText" ) ); 188 // assertTrue( "persistent properties did not survive reload (3)!", ((Integer)textFieldModel.getPropertyValue( "SomeNumericValue" )).equals( new Integer( 42 ) ) ); 189 // cannot check this until the types really survice - at the moment, integers are converted to doubles ... 190 191 // the transient property should not have survived 192 boolean caughtExpected = false; 193 try { textFieldModel.getPropertyValue( "SomeTransientText" ); } 194 catch( UnknownPropertyException e ) { caughtExpected = true; } 195 assertTrue( "transient property did survive reload!", caughtExpected ); 196 197 // There would be more things to check. 198 // For instance, it would be desirable of the property attributes would have survived 199 // the reload, and the property defaults (XPropertyState). 200 // However, the file format currently doesn't allow for this, so those information 201 // is lost when saving the document. 202 } 203 204 /* ------------------------------------------------------------------ */ propertyChange(PropertyChangeEvent _propertyChangeEvent)205 public void propertyChange(PropertyChangeEvent _propertyChangeEvent) 206 { 207 m_propertyChangeEvent = _propertyChangeEvent; 208 } 209 210 /* ------------------------------------------------------------------ */ disposing(EventObject eventObject)211 public void disposing(EventObject eventObject) 212 { 213 // not interested in 214 } 215 } 216