2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "LocalStorage.h"
30 #include "EventNames.h"
31 #include "FileSystem.h"
33 #include "FrameTree.h"
34 #include "LocalStorageArea.h"
36 #include "PageGroup.h"
37 #include "StorageArea.h"
41 typedef HashMap
<String
, LocalStorage
*> LocalStorageMap
;
43 static LocalStorageMap
& localStorageMap()
45 static LocalStorageMap localStorageMap
;
46 return localStorageMap
;
49 PassRefPtr
<LocalStorage
> LocalStorage::localStorage(const String
& path
)
51 const String lookupPath
= path
.isNull() ? String("") : path
;
52 LocalStorageMap::iterator it
= localStorageMap().find(lookupPath
);
53 if (it
== localStorageMap().end()) {
54 RefPtr
<LocalStorage
> localStorage
= adoptRef(new LocalStorage(lookupPath
));
55 localStorageMap().set(lookupPath
, localStorage
.get());
56 return localStorage
.release();
62 LocalStorage::LocalStorage(const String
& path
)
65 // If the path is empty, we know we're never going to be using the thread for anything, so don't start it.
66 // In the future, we might also want to consider removing it from the DOM in that case - <rdar://problem/5960470>
70 m_thread
= LocalStorageThread::create();
72 m_thread
->scheduleImport(this);
75 LocalStorage::~LocalStorage()
77 ASSERT(localStorageMap().get(m_path
) == this);
78 localStorageMap().remove(m_path
);
81 PassRefPtr
<StorageArea
> LocalStorage::storageArea(Frame
* sourceFrame
, SecurityOrigin
* origin
)
83 ASSERT(isMainThread());
85 // FIXME: If the security origin in question has never had a storage area established,
86 // we need to ask a client call if establishing it is okay. If the client denies the request,
87 // this method will return null.
88 // The sourceFrame argument exists for the purpose of asking a client.
89 // To know if an area has previously been established, we need to wait until this LocalStorage
90 // object has finished it's AreaImport task.
93 // FIXME: If the storage area is being established for the first time here, we need to
94 // sync its existance and quota out to disk via an task of type AreaSync
96 RefPtr
<LocalStorageArea
> storageArea
;
97 if (storageArea
= m_storageAreaMap
.get(origin
))
98 return storageArea
.release();
100 storageArea
= LocalStorageArea::create(origin
, this);
101 m_storageAreaMap
.set(origin
, storageArea
);
102 return storageArea
.release();
105 String
LocalStorage::fullDatabaseFilename(SecurityOrigin
* origin
)
107 // FIXME: Once we actually track origin/quota entries to see which origins have local storage established,
108 // we will return an empty path name if the origin isn't allowed to have LocalStorage.
109 // We'll need to wait here until the AreaImport task to complete before making that decision.
111 if (m_path
.isEmpty())
118 if (!makeAllDirectories(m_path
)) {
119 LOG_ERROR("Unabled to create LocalStorage database path %s", m_path
.utf8().data());
123 return pathByAppendingComponent(m_path
, origin
->databaseIdentifier() + ".localstorage");
126 void LocalStorage::performImport()
128 ASSERT(!isMainThread());
130 // FIXME: Import all known local storage origins here along with their quotas
133 void LocalStorage::performSync()
135 ASSERT(!isMainThread());
137 // FIXME: Write out new origins and quotas here
140 void LocalStorage::close()
142 ASSERT(isMainThread());
144 LocalStorageAreaMap::iterator end
= m_storageAreaMap
.end();
145 for (LocalStorageAreaMap::iterator it
= m_storageAreaMap
.begin(); it
!= end
; ++it
)
146 it
->second
->scheduleFinalSync();
149 m_thread
->terminate();
154 bool LocalStorage::scheduleImport(PassRefPtr
<LocalStorageArea
> area
)
156 ASSERT(isMainThread());
159 m_thread
->scheduleImport(area
);
164 void LocalStorage::scheduleSync(PassRefPtr
<LocalStorageArea
> area
)
166 ASSERT(isMainThread());
168 m_thread
->scheduleSync(area
);
171 } // namespace WebCore