sbRemoteSiteLibrary.cpp
Go to the documentation of this file.
1 /*
2 //
3 // BEGIN SONGBIRD GPL
4 //
5 // This file is part of the Songbird web player.
6 //
7 // Copyright(c) 2005-2008 POTI, Inc.
8 // http://songbirdnest.com
9 //
10 // This file may be licensed under the terms of of the
11 // GNU General Public License Version 2 (the "GPL").
12 //
13 // Software distributed under the License is distributed
14 // on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
15 // express or implied. See the GPL for the specific language
16 // governing rights and limitations.
17 //
18 // You should have received a copy of the GPL along with this
19 // program. If not, go to http://www.gnu.org/licenses/gpl.html
20 // or write to the Free Software Foundation, Inc.,
21 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 // END SONGBIRD GPL
24 //
25  */
26 
27 #include "sbRemotePlayer.h"
28 #include "sbRemoteSiteLibrary.h"
29 
30 #include <nsINetUtil.h>
31 #include <nsIPrefService.h>
32 #include <nsIProgrammingLanguage.h>
33 #include <nsIProperties.h>
34 #include <nsISupportsPrimitives.h>
35 #include <nsIURI.h>
36 #include <nsIURL.h>
37 #include <nsIWritablePropertyBag2.h>
38 #include <sbILibraryFactory.h>
39 #include <sbILibraryManager.h>
40 
41 #include <nsComponentManagerUtils.h>
42 #include <nsHashKeys.h>
43 #include <nsMemory.h>
44 #include <nsNetCID.h>
45 #include <nsNetUtil.h>
46 #include <nsServiceManagerUtils.h>
47 #include <nsXPCOMCIDInternal.h>
48 #include <prlog.h>
49 #include <prnetdb.h>
50 #include <sbClassInfoUtils.h>
51 #include <sbLocalDatabaseCID.h>
52 #include <sbStandardProperties.h>
53 #include "sbURIChecker.h"
54 
55 /*
56  * To log this module, set the following environment variable:
57  * NSPR_LOG_MODULES=sbRemoteLibrary:5
58  * LOG_LIB defined in sbRemoteLibraryBase.h/.cpp
59  */
60 #undef LOG
61 #define LOG(args) LOG_LIB(args)
62 
63 const static char* sPublicWProperties[] =
64  { // sbIMediaList
65  "site:name",
66 
67  // sbIRemoteLibrary
68  "site:scanMediaOnCreation"
69  };
70 
71 const static char* sPublicRProperties[] =
72  { // sbIMediaList
73  "site:name",
74  "site:type",
75  "site:length",
76 
77  // sbIRemoteLibrary
78  "site:scanMediaOnCreation",
79  "site:playlists",
80 
81  // sbIScriptableFilterResult
82  "site:artists",
83  "site:albums",
84  "site:genres",
85  "site:years",
86 
87  // sbIRemoteSiteLibrary
88 #ifdef DEBUG
89  "site:filename",
90 #endif
91 
92  // nsIClassInfo
93  "classinfo:classDescription",
94  "classinfo:contractID",
95  "classinfo:classID",
96  "classinfo:implementationLanguage",
97  "classinfo:flags"
98  };
99 
100 const static char* sPublicMethods[] =
101  { // sbIRemoteLibrary
102  "site:createSimpleMediaList",
103  "site:createMediaListFromURL",
104  "site:createMediaItem",
105  "site:getMediaListBySiteID",
106  "site:getPlaylists",
107 
108  // sbIScriptableFilterResult
109  "site:getArtists",
110  "site:getAlbums",
111  "site:getYears",
112  "site:getGenres",
113 
114  // sbIMediaList
115  "site:getItemByGuid",
116  "site:getItemByIndex",
117  "site:enumerateAllItems",
118  "site:enumerateItemsByProperty",
119  "site:indexOf",
120  "site:lastIndexOf",
121  "site:contains",
122  "site:add",
123  "site:addAll",
124  "site:addSome",
125  "site:clear",
126  "site:remove",
127  "site:removeByIndex",
128  "site:getDistinctValuesForProperty",
129 
130  // sbILibraryResource
131  "site:getProperty",
132  "site:setProperty",
133  "site:equals"
134  };
135 
139  nsIClassInfo )
140 
147  sbIMediaList,
148  sbIMediaItem,
150 
151 SB_IMPL_CLASSINFO_INTERFACES_ONLY(sbRemoteSiteLibrary)
152 
154 
155 #define kNotFound -1
156 
158  sbRemoteLibraryBase(aRemotePlayer)
159 {
160  LOG_LIB(("sbRemoteSiteLibrary::sbRemoteSiteLibrary()"));
161 }
162 
164 {
165  LOG_LIB(("sbRemoteSiteLibrary::~sbRemoteSiteLibrary()"));
166 }
167 
168 
169 // ----------------------------------------------------------------------------
170 //
171 // sbIRemoteSiteLibrary
172 //
173 // ----------------------------------------------------------------------------
174 
175 NS_IMETHODIMP
176 sbRemoteSiteLibrary::GetFilename( nsAString &aFilename )
177 {
178  LOG_LIB(("sbRemoteSiteLibrary::GetFilename()"));
179 #ifdef DEBUG
180  aFilename.Assign(mFilename);
181 #endif
182  return NS_OK;
183 }
184 
185 NS_IMETHODIMP
186 sbRemoteSiteLibrary::ConnectToSiteLibrary( const nsACString &aDomain,
187  const nsACString &aPath )
188 {
189  // aDomain and aPath may be empty
190  LOG_LIB(( "sbRemoteSiteLibrary::ConnectToSiteLibrary(domain:%s path:%s)",
191  aDomain.BeginReading(), aPath.BeginReading() ));
192 
193  nsCOMPtr<nsIFile> siteDBFile = GetSiteLibraryFile( aDomain, aPath );
194  if (!siteDBFile) {
195  LOG_LIB(("sbRemoteSiteLibrary::ConnectToSiteLibrary() - no site db file "));
196  return NS_ERROR_FAILURE;
197  }
198 
199  nsresult rv;
200 
201 #ifdef DEBUG
202  rv = siteDBFile->GetLeafName(mFilename);
203  NS_ENSURE_SUCCESS( rv, rv );
204 #endif
205 
206  // Get the library factory to create a new instance from the file
207  nsCOMPtr<sbILibraryFactory> libFactory(
208  do_CreateInstance( SB_LOCALDATABASE_LIBRARYFACTORY_CONTRACTID, &rv ) );
209  NS_ENSURE_SUCCESS( rv, rv );
210 
211  // Get a propertybag to pass in the filename
212  nsCOMPtr<nsIWritablePropertyBag2> propBag(
213  do_CreateInstance( NS_HASH_PROPERTY_BAG_CONTRACTID, &rv ) );
214  NS_ENSURE_SUCCESS( rv, rv );
215 
216  rv = propBag->SetPropertyAsInterface( NS_LITERAL_STRING("databaseFile"),
217  siteDBFile );
218  NS_ENSURE_SUCCESS( rv, rv );
219 
220  // Create the library
221  rv = libFactory->CreateLibrary( propBag, getter_AddRefs(mLibrary) );
222  NS_ENSURE_SUCCESS( rv, rv );
223 
224  rv = mLibrary->SetProperty( NS_LITERAL_STRING( SB_PROPERTY_HIDDEN ),
225  NS_LITERAL_STRING( "1" ) );
226  NS_ENSURE_SUCCESS( rv, rv );
227 
228  // Register the library
229  nsCOMPtr<sbILibraryManager> libraryManager =
230  do_GetService( "@songbirdnest.com/Songbird/library/Manager;1", &rv );
231  NS_ENSURE_SUCCESS( rv, rv );
232 
233  PRBool hasLibrary;
234  rv = libraryManager->HasLibrary( mLibrary, &hasLibrary );
235  NS_ENSURE_SUCCESS( rv, rv );
236 
237  if (!hasLibrary) {
238  rv = libraryManager->RegisterLibrary( mLibrary, PR_FALSE );
239  NS_ENSURE_SUCCESS( rv, rv );
240  }
241 
242  rv = InitInternalMediaList();
243  NS_ENSURE_SUCCESS( rv, rv );
244 
245  return NS_OK;
246 }
247 
248 // ----------------------------------------------------------------------------
249 //
250 // Helper Methods
251 //
252 // ----------------------------------------------------------------------------
253 
254 nsresult
256 {
257  LOG_LIB(("sbRemoteSiteLibrary::InitInternalMediaList()"));
258  NS_ENSURE_STATE(mLibrary);
259 
260  nsCOMPtr<sbIMediaList> mediaList = do_QueryInterface(mLibrary);
261  NS_ENSURE_TRUE( mediaList, NS_ERROR_FAILURE );
262 
263  nsCOMPtr<sbIMediaListView> mediaListView;
264  nsresult rv = mediaList->CreateView( nsnull, getter_AddRefs(mediaListView) );
265  NS_ENSURE_SUCCESS( rv, rv );
266 
268  mediaList,
269  mediaListView );
270  NS_ENSURE_TRUE( mRemSiteMediaList, NS_ERROR_OUT_OF_MEMORY );
271 
272  rv = mRemSiteMediaList->Init();
273  NS_ENSURE_SUCCESS( rv, rv );
274 
275  // base class uses the base list to forward interfaces
277 
278  return rv;
279 }
280 
281 already_AddRefed<nsIFile>
282 sbRemoteSiteLibrary::GetSiteLibraryFile( const nsACString &aDomain,
283  const nsACString &aPath )
284 {
285  // aPath and aDomain may be empty
286  LOG_LIB(( "sbRemoteSiteLibrary::GetSiteLibraryFile(domain:%s path:%s)",
287  aDomain.BeginReading(),
288  aPath.BeginReading() ));
289 
290  nsCOMPtr<nsIURI> siteURI = GetURI();
291  if (!siteURI) {
292  LOG_LIB(("sbRemoteSiteLibrary::GetSiteLibraryFile() -- FAILED to get URI"));
293  return nsnull;
294  }
295 
296  nsCString domain(aDomain);
297  nsCString path(aPath);
298  nsresult rv = sbURIChecker::CheckURI(domain, path, siteURI);
299  if ( NS_FAILED(rv) ) {
300  // this should not be possible, sbRemotePlayer::SetSiteScope() should
301  // have done the exact same check already
302  LOG_LIB(("sbRemoteSiteLibrary::GetSiteLibraryFile() -- FAILED URI Check"));
303  return nsnull;
304  }
305 
306  nsString filename;
307  rv = GetFilenameForSiteLibraryInternal( domain, path, PR_FALSE, filename );
308  NS_ENSURE_SUCCESS( rv, nsnull );
309 
310  // get the directory service
311  nsCOMPtr<nsIProperties> directoryService(
312  do_GetService( NS_DIRECTORY_SERVICE_CONTRACTID, &rv ) );
313  NS_ENSURE_SUCCESS( rv, nsnull );
314 
315  // get the users profile directory
316  nsCOMPtr<nsIFile> siteDBFile;
317  rv = directoryService->Get( "ProfD", NS_GET_IID(nsIFile),
318  getter_AddRefs(siteDBFile) );
319  NS_ENSURE_SUCCESS( rv, nsnull );
320 
321  // extend the path and add the file
322  siteDBFile->Append( NS_LITERAL_STRING("db") );
323  siteDBFile->Append(filename);
324 
325  nsIFile* outFile = nsnull;
326  siteDBFile.swap(outFile);
327 
328  return outFile;
329 }
330 
331 already_AddRefed<nsIURI>
333 {
334  LOG_LIB(("sbRemoteSiteLibrary::GetURI()"));
335 
336  nsresult rv;
337  nsCOMPtr<sbISecurityMixin> mixin( do_QueryInterface( mSecurityMixin, &rv ) );
338  NS_ENSURE_SUCCESS( rv, nsnull );
339 
340  // GetCodebase AddRef's for us here.
341  nsIURI* siteURI;
342  rv = mixin->GetCodebase( &siteURI );
343  NS_ENSURE_SUCCESS( rv, nsnull );
344 
345  return siteURI;
346 }
347 
348 /* static */
349 nsresult
351  const nsACString& aPath,
352  PRBool aDoFixup,
353  nsAString& _retval )
354 {
355  // aDomain and aPath may be empty
356 
357  nsresult rv;
358 
359  nsCString domain, path;
360  if (aDoFixup) {
361  // External callers will need to have these arguments validated.
362  rv = sbURIChecker::FixupDomain( aDomain, domain );
363  NS_ENSURE_SUCCESS( rv, rv );
364 
365  rv = sbURIChecker::FixupPath( aPath, path );
366  NS_ENSURE_SUCCESS( rv, rv );
367  }
368  else {
369  // Internal callers should have already performed a more rigorous validation
370  // of the arguments so we don't need to do anything special here.
371  domain.Assign(aDomain);
372  path.Assign(aPath);
373  }
374 
375  // Do some character escaping
376  nsCOMPtr<nsINetUtil> netUtil = do_GetService( NS_NETUTIL_CONTRACTID, &rv );
377  NS_ENSURE_SUCCESS( rv, nsnull );
378 
379  nsCString escapedDomain;
380  rv = netUtil->EscapeString( domain, nsINetUtil::ESCAPE_XALPHAS,
381  escapedDomain );
382  NS_ENSURE_SUCCESS( rv, nsnull );
383 
384  nsCString escapedPath;
385  rv = netUtil->EscapeString( path, nsINetUtil::ESCAPE_XALPHAS,
386  escapedPath );
387  NS_ENSURE_SUCCESS( rv, nsnull );
388 
389  nsString filename = NS_ConvertUTF8toUTF16(escapedDomain);
390  filename.Append( NS_ConvertUTF8toUTF16(escapedPath) );
391  filename.AppendLiteral(".db");
392 
393  _retval.Assign(filename);
394  return NS_OK;
395 }
#define SB_IMPL_SECURITYCHECKEDCOMP_INIT(_class)
Definition: sbRemoteAPI.h:82
return NS_OK
_updateCookies aPath
static nsresult CheckURI(nsACString &aDomain, nsACString &aPath, nsIURI *aURI)
sbRemoteSiteLibrary(sbRemotePlayer *aRemotePlayer)
static const char * sPublicRProperties[]
static nsresult FixupDomain(const nsACString &aDomain, nsACString &_retval)
#define SB_PROPERTY_HIDDEN
NS_IMPL_CI_INTERFACE_GETTER8(sbLocalDatabaseSmartMediaList, nsIClassInfo, nsISupportsWeakReference, sbILibraryResource, sbILocalDatabaseSmartMediaList, sbIMediaItem, sbIMediaList, sbIMediaListListener, nsIObserver)
readonly attribute AString filename
The filename of the library file Set only in debug builds.
A brief description of the contents of this interface.
virtual nsresult InitInternalMediaList()
nsISecurityCheckedComponent
static const char * sPublicMethods[]
#define SB_LOCALDATABASE_LIBRARYFACTORY_CONTRACTID
An interface for a sandbox library created by the website.
already_AddRefed< nsIFile > GetSiteLibraryFile(const nsACString &aDomain, const nsACString &aPath)
A marker interface for objects that aggregate the security mixin.
nsRefPtr< sbRemoteSiteMediaList > mRemSiteMediaList
nsRefPtr< sbRemoteMediaListBase > mRemMediaList
static nsresult FixupPath(nsIURI *aURI, nsACString &_retval)
nsCOMPtr< nsISecurityCheckedComponent > mSecurityMixin
var libraryManager
An interface to control a media library from remote web pages.
The result of a filtering expression in a library.
nsCOMPtr< sbILibrary > mLibrary
Interface that defines a single item of media in the system.
nsRefPtr< sbRemotePlayer > mRemotePlayer
#define SB_IMPL_CLASSINFO_INTERFACES_ONLY(_class)
already_AddRefed< nsIURI > GetURI()
An interface to control a media list from remote web pages.
static const char * sPublicWProperties[]
static nsresult GetFilenameForSiteLibraryInternal(const nsACString &aDomain, const nsACString &aPath, PRBool aDoFixup, nsAString &_retval)
#define LOG_LIB(args)
NS_IMPL_ISUPPORTS_INHERITED2(sbRemoteSiteLibrary, sbRemoteLibraryBase, sbIRemoteSiteLibrary, nsIClassInfo) NS_IMPL_CI_INTERFACE_GETTER8(sbRemoteSiteLibrary