LibreOffice Module ucb (master)  1
ucpext_provider.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include "ucpext_provider.hxx"
21 #include "ucpext_content.hxx"
22 
23 #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
25 #include <osl/mutex.hxx>
26 #include <rtl/ustrbuf.hxx>
27 
28 
29 namespace ucb { namespace ucp { namespace ext
30 {
31 
32 
33  using ::com::sun::star::uno::Reference;
34  using ::com::sun::star::uno::XInterface;
35  using ::com::sun::star::uno::RuntimeException;
36  using ::com::sun::star::uno::Sequence;
37  using ::com::sun::star::ucb::XContentIdentifier;
38  using ::com::sun::star::ucb::IllegalIdentifierException;
39  using ::com::sun::star::ucb::XContent;
40  using ::com::sun::star::uno::XComponentContext;
41 
42 
43  //= ContentProvider
44 
45 
47  :ContentProvider_Base( rxContext )
48  {
49  }
50 
51 
53  {
54  }
55 
56 
58  {
59  return "org.openoffice.comp.ucp.ext.ContentProvider";
60  }
61 
62 
64  {
66  }
67 
68 
70  {
71  return { "com.sun.star.ucb.ContentProvider", "com.sun.star.ucb.ExtensionContentProvider" };
72  }
73 
74 
76  {
78  }
79 
80 
82  {
83  return *( new ContentProvider( i_rContext ) );
84  }
85 
86 
88  {
89  return "vnd.sun.star.extension://";
90  }
91 
92 
94  {
95  return "application/vnd.sun.star.extension-content";
96  }
97 
98 
99  namespace
100  {
101  void lcl_ensureAndTransfer( OUString& io_rIdentifierFragment, OUStringBuffer& o_rNormalization, const sal_Unicode i_nLeadingChar )
102  {
103  if ( ( io_rIdentifierFragment.isEmpty() ) || ( io_rIdentifierFragment[0] != i_nLeadingChar ) )
104  throw IllegalIdentifierException();
105  io_rIdentifierFragment = io_rIdentifierFragment.copy( 1 );
106  o_rNormalization.append( i_nLeadingChar );
107  }
108  }
109 
110 
111  Reference< XContent > SAL_CALL ContentProvider::queryContent( const Reference< XContentIdentifier >& i_rIdentifier )
112  {
113  // Check URL scheme...
114  const OUString sScheme( "vnd.sun.star.extension" );
115  if ( !i_rIdentifier->getContentProviderScheme().equalsIgnoreAsciiCase( sScheme ) )
116  throw IllegalIdentifierException();
117 
118  // normalize the identifier
119  const OUString sIdentifier( i_rIdentifier->getContentIdentifier() );
120 
121  // the scheme needs to be lower-case
122  OUStringBuffer aComposer;
123  aComposer.append( sIdentifier.copy( 0, sScheme.getLength() ).toAsciiLowerCase() );
124 
125  // one : is required after the scheme
126  OUString sRemaining( sIdentifier.copy( sScheme.getLength() ) );
127  lcl_ensureAndTransfer( sRemaining, aComposer, ':' );
128 
129  // and at least one /
130  lcl_ensureAndTransfer( sRemaining, aComposer, '/' );
131 
132  // the normalized form requires one additional /, but we also accept identifiers which don't have it
133  if ( sRemaining.isEmpty() )
134  {
135  // the root content is a special case, it requires /
136  aComposer.append( "//" );
137  }
138  else
139  {
140  if ( sRemaining[0] != '/' )
141  {
142  aComposer.append( '/' );
143  aComposer.append( sRemaining );
144  }
145  else
146  {
147  lcl_ensureAndTransfer( sRemaining, aComposer, '/' );
148  // by now, we moved "vnd.sun.star.extension://" from the URL to aComposer
149  if ( sRemaining.isEmpty() )
150  {
151  // again, it's the root content, but one / is missing
152  aComposer.append( '/' );
153  }
154  else
155  {
156  aComposer.append( sRemaining );
157  }
158  }
159  }
160  const Reference< XContentIdentifier > xNormalizedIdentifier( new ::ucbhelper::ContentIdentifier( aComposer.makeStringAndClear() ) );
161 
162  ::osl::MutexGuard aGuard( m_aMutex );
163 
164  // check if a content with given id already exists...
165  Reference< XContent > xContent( queryExistingContent( xNormalizedIdentifier ).get() );
166  if ( xContent.is() )
167  return xContent;
168 
169  // create a new content
170  xContent = new Content( m_xContext, this, xNormalizedIdentifier );
171  if ( !xContent->getIdentifier().is() )
172  throw IllegalIdentifierException();
173 
174  registerNewContent( xContent );
175  return xContent;
176  }
177 
178 
179 } } } // namespace ucb::ucp::ext
180 
181 
182 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static css::uno::Sequence< OUString > getSupportedServiceNames_static()
ContentProvider(const css::uno::Reference< css::uno::XComponentContext > &rxContext)
static OUString getArtificialNodeContentType()
static OUString getImplementationName_static()
virtual ~ContentProvider() override
sal_uInt16 sal_Unicode
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
::ucbhelper::ContentProviderImplHelper ContentProvider_Base
virtual css::uno::Reference< css::ucb::XContent > SAL_CALL queryContent(const css::uno::Reference< css::ucb::XContentIdentifier > &Identifier) override
rtl::Reference< ContentImplHelper > queryExistingContent(const css::uno::Reference< css::ucb::XContentIdentifier > &Identifier)
css::uno::Reference< css::uno::XComponentContext > m_xContext
void registerNewContent(const css::uno::Reference< css::ucb::XContent > &xContent)
virtual OUString SAL_CALL getImplementationName() override
static css::uno::Reference< css::uno::XInterface > Create(const css::uno::Reference< css::uno::XComponentContext > &i_rContext)