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::ucp::ext
30 {
31 
32 
33  using ::com::sun::star::uno::Reference;
34  using ::com::sun::star::uno::XInterface;
35  using ::com::sun::star::uno::Sequence;
36  using ::com::sun::star::ucb::XContentIdentifier;
37  using ::com::sun::star::ucb::IllegalIdentifierException;
38  using ::com::sun::star::ucb::XContent;
39  using ::com::sun::star::uno::XComponentContext;
40 
41 
42  //= ContentProvider
43 
44 
46  :ContentProvider_Base( rxContext )
47  {
48  }
49 
50 
52  {
53  }
54 
55 
57  {
58  return "org.openoffice.comp.ucp.ext.ContentProvider";
59  }
60 
61 
63  {
65  }
66 
67 
69  {
70  return { "com.sun.star.ucb.ContentProvider", "com.sun.star.ucb.ExtensionContentProvider" };
71  }
72 
73 
75  {
77  }
78 
79 
81  {
82  return *( new ContentProvider( i_rContext ) );
83  }
84 
85 
87  {
88  return "vnd.sun.star.extension://";
89  }
90 
91 
93  {
94  return "application/vnd.sun.star.extension-content";
95  }
96 
97 
98  namespace
99  {
100  void lcl_ensureAndTransfer( OUString& io_rIdentifierFragment, OUStringBuffer& o_rNormalization, const sal_Unicode i_nLeadingChar )
101  {
102  if ( ( io_rIdentifierFragment.isEmpty() ) || ( io_rIdentifierFragment[0] != i_nLeadingChar ) )
103  throw IllegalIdentifierException();
104  io_rIdentifierFragment = io_rIdentifierFragment.copy( 1 );
105  o_rNormalization.append( i_nLeadingChar );
106  }
107  }
108 
109 
110  Reference< XContent > SAL_CALL ContentProvider::queryContent( const Reference< XContentIdentifier >& i_rIdentifier )
111  {
112  // Check URL scheme...
113  const OUString sScheme( "vnd.sun.star.extension" );
114  if ( !i_rIdentifier->getContentProviderScheme().equalsIgnoreAsciiCase( sScheme ) )
115  throw IllegalIdentifierException();
116 
117  // normalize the identifier
118  const OUString sIdentifier( i_rIdentifier->getContentIdentifier() );
119 
120  // the scheme needs to be lower-case
121  OUStringBuffer aComposer;
122  aComposer.append( sIdentifier.copy( 0, sScheme.getLength() ).toAsciiLowerCase() );
123 
124  // one : is required after the scheme
125  OUString sRemaining( sIdentifier.copy( sScheme.getLength() ) );
126  lcl_ensureAndTransfer( sRemaining, aComposer, ':' );
127 
128  // and at least one /
129  lcl_ensureAndTransfer( sRemaining, aComposer, '/' );
130 
131  // the normalized form requires one additional /, but we also accept identifiers which don't have it
132  if ( sRemaining.isEmpty() )
133  {
134  // the root content is a special case, it requires /
135  aComposer.append( "//" );
136  }
137  else
138  {
139  if ( sRemaining[0] != '/' )
140  {
141  aComposer.append( '/' );
142  aComposer.append( sRemaining );
143  }
144  else
145  {
146  lcl_ensureAndTransfer( sRemaining, aComposer, '/' );
147  // by now, we moved "vnd.sun.star.extension://" from the URL to aComposer
148  if ( sRemaining.isEmpty() )
149  {
150  // again, it's the root content, but one / is missing
151  aComposer.append( '/' );
152  }
153  else
154  {
155  aComposer.append( sRemaining );
156  }
157  }
158  }
159  const Reference< XContentIdentifier > xNormalizedIdentifier( new ::ucbhelper::ContentIdentifier( aComposer.makeStringAndClear() ) );
160 
161  ::osl::MutexGuard aGuard( m_aMutex );
162 
163  // check if a content with given id already exists...
164  Reference< XContent > xContent( queryExistingContent( xNormalizedIdentifier ).get() );
165  if ( xContent.is() )
166  return xContent;
167 
168  // create a new content
169  xContent = new Content( m_xContext, this, xNormalizedIdentifier );
170  if ( !xContent->getIdentifier().is() )
171  throw IllegalIdentifierException();
172 
174  return xContent;
175  }
176 
177 
178 } // namespace ucb::ucp::ext
179 
180 
181 /* 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)
uno::Reference< ucb::XContent > xContent