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 #include <sal/cppunit.h>
29 #include <rtl/ustrbuf.hxx>
30 
31 #include <com/sun/star/util/DateTime.hpp>
32 #include <com/sun/star/util/Date.hpp>
33 #include <com/sun/star/util/Duration.hpp>
34 
35 #include <sfx2/Metadatable.hxx>
36 #include <sfx2/XmlIdRegistry.hxx>
37 
38 
39 using namespace ::com::sun::star;
40 
41 
42 namespace {
43 
44 class MetadatableTest
45     : public ::CppUnit::TestFixture
46 {
47 public:
48     virtual void setUp();
49     virtual void tearDown();
50 
51     void test();
52 
53     CPPUNIT_TEST_SUITE(MetadatableTest);
54     CPPUNIT_TEST(test);
55     CPPUNIT_TEST_SUITE_END();
56 
57 private:
58 };
59 
60 void MetadatableTest::setUp()
61 {
62 }
63 
64 void MetadatableTest::tearDown()
65 {
66 }
67 
68 
69 class MockMetadatable
70     : public ::sfx2::Metadatable
71 {
72 private:
73     ::sfx2::IXmlIdRegistry & m_rRegistry;
74 
75 public:
76     MockMetadatable(::sfx2::IXmlIdRegistry & i_rReg,
77             bool const i_isInClip = false)
78         : m_rRegistry(i_rReg)
79         , m_bInClipboard(i_isInClip), m_bInUndo(false), m_bInContent(true) {}
80     bool m_bInClipboard;
81     bool m_bInUndo;
82     bool m_bInContent;
83     virtual bool IsInClipboard() const { return m_bInClipboard; }
84     virtual bool IsInUndo() const { return m_bInUndo; }
85     virtual bool IsInContent() const { return m_bInContent; }
86     virtual ::sfx2::IXmlIdRegistry& GetRegistry() { return m_rRegistry; }
87     virtual ::com::sun::star::uno::Reference<
88         ::com::sun::star::rdf::XMetadatable > MakeUnoObject() { return 0; }
89 };
90 
91 static bool operator==(beans::StringPair p1, beans::StringPair p2)
92 {
93     return p1.First == p2.First && p1.Second == p2.Second;
94 }
95 
96 void MetadatableTest::test()
97 {
98     OSL_TRACE("SwMetadatable test(): start\n");
99     ::std::auto_ptr< ::sfx2::IXmlIdRegistry > const pReg(
100         ::sfx2::createXmlIdRegistry(false) );
101     ::std::auto_ptr< ::sfx2::IXmlIdRegistry > const pRegClip(
102         ::sfx2::createXmlIdRegistry(true) );
103 
104     MockMetadatable m1(*pReg);
105     MockMetadatable m2(*pReg);
106     MockMetadatable m3(*pReg);
107     MockMetadatable m4(*pReg);
108     MockMetadatable m5(*pReg);
109     ::rtl::OUString empty;
110     ::rtl::OUString content( ::rtl::OUString::createFromAscii("content.xml") );
111     ::rtl::OUString styles ( ::rtl::OUString::createFromAscii("styles.xml") );
112     ::rtl::OUString sid1( ::rtl::OUString::createFromAscii("id1") );
113     ::rtl::OUString sid2( ::rtl::OUString::createFromAscii("id2") );
114     ::rtl::OUString sid3( ::rtl::OUString::createFromAscii("id3") );
115     ::rtl::OUString sid4( ::rtl::OUString::createFromAscii("id4") );
116     beans::StringPair id1(content, sid1);
117     beans::StringPair id2(content, sid2);
118     beans::StringPair id3(content, sid3);
119     beans::StringPair id4(styles,  sid4);
120     beans::StringPair id3e(empty,  sid3);
121     beans::StringPair id4e(empty,  sid4);
122     m1.SetMetadataReference(id1);
123     CPPUNIT_ASSERT_MESSAGE("set failed", m1.GetMetadataReference() == id1);
124     try {
125         m2.SetMetadataReference(id1);
126         CPPUNIT_ASSERT_MESSAGE("set duplicate succeeded", false);
127     } catch (lang::IllegalArgumentException) { }
128     m1.SetMetadataReference(id1);
129     CPPUNIT_ASSERT_MESSAGE("set failed (existing)",
130             m1.GetMetadataReference() == id1);
131     m1.EnsureMetadataReference();
132     CPPUNIT_ASSERT_MESSAGE("ensure failed (existing)",
133             m1.GetMetadataReference() == id1);
134 
135     m2.EnsureMetadataReference();
136     beans::StringPair m2id(m2.GetMetadataReference());
137     CPPUNIT_ASSERT_MESSAGE("ensure failed", m2id.Second.getLength());
138     m2.EnsureMetadataReference();
139     CPPUNIT_ASSERT_MESSAGE("ensure failed (idempotent)",
140             m2.GetMetadataReference() == m2id);
141 
142     m1.m_bInUndo = true;
143     CPPUNIT_ASSERT_MESSAGE("move to undo failed",
144             !m1.GetMetadataReference().Second.getLength());
145 
146     m1.m_bInUndo = false;
147     CPPUNIT_ASSERT_MESSAGE("move from undo failed",
148             m1.GetMetadataReference() == id1);
149 
150     m1.m_bInUndo = true;
151     try {
152         m2.SetMetadataReference(id1); // steal!
153     } catch (lang::IllegalArgumentException &) {
154         CPPUNIT_FAIL("set duplicate to undo failed");
155     }
156     m1.m_bInUndo = false;
157     CPPUNIT_ASSERT_MESSAGE("move from undo: duplicate",
158             !m1.GetMetadataReference().Second.getLength());
159 
160     m3.RegisterAsCopyOf(m2);
161     CPPUNIT_ASSERT_MESSAGE("copy: source", m2.GetMetadataReference() == id1);
162     CPPUNIT_ASSERT_MESSAGE("copy: duplicate",
163             !m3.GetMetadataReference().Second.getLength());
164     m4.RegisterAsCopyOf(m3);
165     CPPUNIT_ASSERT_MESSAGE("copy: source", m2.GetMetadataReference() == id1);
166     CPPUNIT_ASSERT_MESSAGE("copy: duplicate",
167             !m3.GetMetadataReference().Second.getLength());
168     CPPUNIT_ASSERT_MESSAGE("copy: duplicate",
169             !m4.GetMetadataReference().Second.getLength());
170     m2.m_bInUndo = true;
171     CPPUNIT_ASSERT_MESSAGE("duplicate to undo",
172             m3.GetMetadataReference() == id1);
173     CPPUNIT_ASSERT_MESSAGE("duplicate to undo",
174             !m2.GetMetadataReference().Second.getLength());
175     m2.m_bInUndo = false;
176     CPPUNIT_ASSERT_MESSAGE("duplicate from undo",
177             m2.GetMetadataReference() == id1);
178     CPPUNIT_ASSERT_MESSAGE("duplicate from undo",
179             !m3.GetMetadataReference().Second.getLength());
180 
181     m4.EnsureMetadataReference(); // new!
182     beans::StringPair m4id(m4.GetMetadataReference());
183     CPPUNIT_ASSERT_MESSAGE("ensure on duplicate",
184             m4id.Second.getLength() && !(m4id == id1));
185 
186     MockMetadatable mc1(*pRegClip, true); // in clipboard
187     MockMetadatable mc2(*pRegClip, true);
188     MockMetadatable mc3(*pRegClip, true);
189     MockMetadatable mc4(*pRegClip, true);
190     MockMetadatable m2p(*pReg);
191     MockMetadatable m3p(*pReg);
192 
193     mc1.SetMetadataReference(id2);
194     CPPUNIT_ASSERT_MESSAGE("set failed", mc1.GetMetadataReference() == id2);
195     try {
196         mc2.SetMetadataReference(id2);
197         CPPUNIT_FAIL("set duplicate succeeded");
198     } catch (lang::IllegalArgumentException) { }
199     mc1.SetMetadataReference(id2);
200     CPPUNIT_ASSERT_MESSAGE("set failed (existing)",
201             mc1.GetMetadataReference() == id2);
202     mc1.EnsureMetadataReference();
203     CPPUNIT_ASSERT_MESSAGE("ensure failed (existing)",
204             mc1.GetMetadataReference() == id2);
205     mc2.EnsureMetadataReference();
206     beans::StringPair mc2id(mc2.GetMetadataReference());
207     CPPUNIT_ASSERT_MESSAGE("ensure failed", mc2id.Second.getLength());
208     mc2.EnsureMetadataReference();
209     CPPUNIT_ASSERT_MESSAGE("ensure failed (idempotent)",
210             mc2.GetMetadataReference() == mc2id);
211     mc2.RemoveMetadataReference();
212     CPPUNIT_ASSERT_MESSAGE("remove failed",
213             !mc2.GetMetadataReference().Second.getLength());
214 
215     // set up mc2 as copy of m2 and mc3 as copy of m3
216     mc3.RegisterAsCopyOf(m3);
217     CPPUNIT_ASSERT_MESSAGE("copy to clipboard (latent)",
218             !mc3.GetMetadataReference().Second.getLength() );
219     mc2.RegisterAsCopyOf(m2);
220     CPPUNIT_ASSERT_MESSAGE("copy to clipboard (non-latent)",
221             mc2.GetMetadataReference() == id1);
222     // paste mc2 to m2p and mc3 to m3p
223     m2p.RegisterAsCopyOf(mc2);
224     CPPUNIT_ASSERT_MESSAGE("paste from clipboard (non-latent)",
225             !m2p.GetMetadataReference().Second.getLength() );
226     m3p.RegisterAsCopyOf(mc3);
227     CPPUNIT_ASSERT_MESSAGE("paste from clipboard (latent)",
228             !m3p.GetMetadataReference().Second.getLength() );
229     // delete m2, m2p, m3
230     m2.RemoveMetadataReference();
231     CPPUNIT_ASSERT_MESSAGE("remove failed",
232             !m2.GetMetadataReference().Second.getLength());
233     CPPUNIT_ASSERT_MESSAGE("paste-remove (non-latent)",
234             m2p.GetMetadataReference() == id1);
235     m2p.RemoveMetadataReference();
236     CPPUNIT_ASSERT_MESSAGE("remove failed",
237             !m2p.GetMetadataReference().Second.getLength());
238     CPPUNIT_ASSERT_MESSAGE("paste-remove2 (non-latent)",
239             m3.GetMetadataReference() == id1);
240     m3.RemoveMetadataReference();
241     CPPUNIT_ASSERT_MESSAGE("remove failed",
242             !m3.GetMetadataReference().Second.getLength());
243     CPPUNIT_ASSERT_MESSAGE("paste-remove (latent)",
244             m3p.GetMetadataReference() == id1);
245     // delete mc2
246     mc2.SetMetadataReference(beans::StringPair());
247     CPPUNIT_ASSERT_MESSAGE("in clipboard becomes non-latent",
248             !mc3.GetMetadataReference().Second.getLength() );
249     // paste mc2
250     m2p.RegisterAsCopyOf(mc2);
251     CPPUNIT_ASSERT_MESSAGE("remove-paste",
252             !m2p.GetMetadataReference().Second.getLength());
253     CPPUNIT_ASSERT_MESSAGE("remove-paste (stolen)",
254             m3p.GetMetadataReference() == id1);
255 
256     // auto-detect stream
257     m5.SetMetadataReference(id3e);
258     CPPUNIT_ASSERT_MESSAGE("auto-detect (content)",
259             m5.GetMetadataReference() == id3);
260     m5.m_bInContent = false;
261     m5.SetMetadataReference(id4e);
262     CPPUNIT_ASSERT_MESSAGE("auto-detect (styles)",
263             m5.GetMetadataReference() == id4);
264 
265     OSL_TRACE("sfx2::Metadatable test(): finished\n");
266 }
267 
268 
269 CPPUNIT_TEST_SUITE_REGISTRATION(MetadatableTest);
270 
271 }
272 
273 CPPUNIT_PLUGIN_IMPLEMENT();
274 
275