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