1/*
2 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
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.
12 *
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.
24 */
25
26#include "config.h"
27#include "StorageNamespace.h"
28
29// FIXME: Do we need all of these
30#include "CString.h"
31#include "EventNames.h"
32#include "FileSystem.h"
33#include "Frame.h"
34#include "FrameTree.h"
35#include "Page.h"
36#include "PageGroup.h"
37#include "StorageArea.h"
38#include "StorageSyncManager.h"
39#include <wtf/StdLibExtras.h>
40
41namespace WebCore {
42
43typedef HashMap<String, StorageNamespace*> LocalStorageNamespaceMap;
44
45static LocalStorageNamespaceMap& localStorageNamespaceMap()
46{
47 DEFINE_STATIC_LOCAL(LocalStorageNamespaceMap, localStorageNamespaceMap, ());
48 return localStorageNamespaceMap;
49}
50
51PassRefPtr<StorageNamespace> StorageNamespace::localStorageNamespace(const String& path)
52{
53 const String lookupPath = path.isNull() ? String("") : path;
54 LocalStorageNamespaceMap::iterator it = localStorageNamespaceMap().find(lookupPath);
55 if (it == localStorageNamespaceMap().end()) {
56 RefPtr<StorageNamespace> storageNamespace = adoptRef(new StorageNamespace(LocalStorage, lookupPath));
57 localStorageNamespaceMap().set(lookupPath, storageNamespace.get());
58 return storageNamespace.release();
59 }
60
61 return it->second;
62}
63
64PassRefPtr<StorageNamespace> StorageNamespace::sessionStorageNamespace()
65{
66 return adoptRef(new StorageNamespace(SessionStorage, String()));
67}
68
69StorageNamespace::StorageNamespace(StorageType storageType, const String& path)
70 : m_storageType(storageType)
71 , m_path(path.copy()) // FIXME: Is the .copy necessary?
72 , m_syncManager(0)
73#ifndef NDEBUG
74 , m_isShutdown(false)
75#endif
76{
77 if (m_storageType == LocalStorage && !m_path.isEmpty())
78 m_syncManager = StorageSyncManager::create(m_path);
79}
80
81StorageNamespace::~StorageNamespace()
82{
83 ASSERT(isMainThread());
84
85 if (m_storageType == LocalStorage) {
86 ASSERT(localStorageNamespaceMap().get(m_path) == this);
87 localStorageNamespaceMap().remove(m_path);
88 }
89}
90
91PassRefPtr<StorageNamespace> StorageNamespace::copy()
92{
93 ASSERT(isMainThread());
94 ASSERT(!m_isShutdown);
95
96 RefPtr<StorageNamespace> newNamespace = adoptRef(new StorageNamespace(m_storageType, m_path));
97
98 StorageAreaMap::iterator end = m_storageAreaMap.end();
99 for (StorageAreaMap::iterator i = m_storageAreaMap.begin(); i != end; ++i) {
100 RefPtr<StorageArea> areaCopy = i->second->copy(i->first.get());
101 newNamespace->m_storageAreaMap.set(i->first, areaCopy.release());
102 }
103
104 return newNamespace.release();
105}
106
107PassRefPtr<StorageArea> StorageNamespace::storageArea(SecurityOrigin* origin)
108{
109 ASSERT(isMainThread());
110 ASSERT(!m_isShutdown);
111
112 RefPtr<StorageArea> storageArea;
113 if (storageArea = m_storageAreaMap.get(origin))
114 return storageArea.release();
115
116 storageArea = StorageArea::create(m_storageType, origin, m_syncManager);
117 m_storageAreaMap.set(origin, storageArea);
118 return storageArea.release();
119}
120
121void StorageNamespace::close()
122{
123 ASSERT(isMainThread());
124 ASSERT(!m_isShutdown);
125
126 StorageAreaMap::iterator end = m_storageAreaMap.end();
127 for (StorageAreaMap::iterator it = m_storageAreaMap.begin(); it != end; ++it)
128 it->second->close();
129
130#ifndef NDEBUG
131 m_isShutdown = true;
132#endif
133}
134
135} // namespace WebCore