LunaSysMgr
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MimeSystem.h
Go to the documentation of this file.
1 /* @@@LICENSE
2 *
3 * Copyright (c) 2009-2012 Hewlett-Packard Development Company, L.P.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * LICENSE@@@ */
18 
19 
20 
21 
22 #ifndef MIMESYSTEM_H_
23 #define MIMESYSTEM_H_
24 
25 #include "Common.h"
26 
27 #include <string>
28 #include <vector>
29 #include <map>
30 #include <set>
31 #include <algorithm>
32 
33 #include "Mutex.h"
34 #include "CmdResourceHandlers.h"
35 
37 {
38 public:
39 
40  class VerbInfo {
41  public:
42  VerbInfo(const std::string& verb,const std::string& params,const std::string handlerAppId, uint32_t handlerIndex) :
43  m_verb(verb) , m_params(params) , m_handlerAppId(handlerAppId) , m_handlerIndex(handlerIndex) , m_valid(true) {}
44  VerbInfo() : m_verb("") , m_params("") , m_handlerAppId("") , m_handlerIndex(0) , m_valid(false) {}
45  VerbInfo(const VerbInfo& c) {
46  m_valid = c.m_valid;
49  m_verb = c.m_verb;
50  m_params = c.m_params;
51  }
52 
54  if (&c == this)
55  return *this;
56 
57  m_valid = c.m_valid;
60  m_verb = c.m_verb;
61  m_params = c.m_params;
62  return *this;
63  }
64 
65  std::string m_verb;
66  std::string m_params;
67  std::string m_handlerAppId;
68  uint32_t m_handlerIndex;
69  bool m_valid;
70 
71  };
72 
73 public:
74 
75  static MimeSystem * instance();
76  static MimeSystem * instance(const std::string& baseConfigFile);
77  static MimeSystem * instance(const std::string& baseConfigFile,const std::string& customizedConfigFile);
78 
79  std::string getActiveAppIdForResource(std::string mimeType);
80  int getAllAppIdForResource(std::string mimeType,std::string& r_active,std::vector<std::string>& r_handlerAppIds);
81 
82  ResourceHandler getActiveHandlerForResource(std::string mimeType);
83  int getAllHandlersForResource(std::string mimeType,ResourceHandler& r_active,std::vector<ResourceHandler>& r_handlers);
84 
85  std::string getActiveAppIdForRedirect(const std::string& url,bool doNotUseRegexpMatch,bool disallowSchemeForms);
86  int getAllAppIdForRedirect(const std::string& url,bool doNotUseRegexpMatch,std::string& r_active,std::vector<std::string>& r_handlerAppIds);
87 
88  RedirectHandler getActiveHandlerForRedirect(const std::string& url,bool doNotUseRegexpMatch,bool disallowSchemeForms);
89  int getAllHandlersForRedirect(const std::string& url,bool doNotUseRegexpMatch,RedirectHandler& r_active,std::vector<RedirectHandler>& r_handlers);
90 
91  std::string getAppIdByVerbForResource(std::string mimeType,const std::string& verb,std::string& r_params,uint32_t& r_index);
92  ResourceHandler getHandlerByVerbForResource(std::string mimeType,const std::string& verb);
93  int getAllHandlersByVerbForResource(std::string mimeType,const std::string& verb,std::vector<ResourceHandler>& r_handlers);
94  int getAllAppIdByVerbForResource(std::string mimeType,const std::string& verb,std::vector<VerbInfo>& r_handlers);
95 
96  std::string getAppIdByVerbForRedirect(const std::string& url,bool disallowSchemeForms,const std::string& verb,std::string& r_params,uint32_t& r_index);
97  RedirectHandler getHandlerByVerbForRedirect(const std::string& url,bool disallowSchemeForms,const std::string& verb);
98  int getAllHandlersByVerbForRedirect(const std::string& url,const std::string& verb,std::vector<RedirectHandler>& r_handlers);
99  int getAllAppIdByVerbForRedirect(const std::string& url,const std::string& verb,std::vector<VerbInfo>& r_handlers);
100 
101  RedirectHandler getRedirectHandlerDirect(const uint32_t index);
102  ResourceHandler getResourceHandlerDirect(const uint32_t index);
103 
104  int removeAllForAppId(const std::string& appId);
105  int removeAllForMimeType(std::string mimeType);
106  int removeAllForUrl(const std::string& url);
107 
108  int addResourceHandler(std::string& extension,std::string mimeType,bool shouldDownload,const std::string appId,const std::map<std::string,std::string> * pVerbs,bool sysDefault);
109  int addResourceHandler(std::string extension,bool shouldDownload,const std::string appId,const std::map<std::string,std::string> * pVerbs,bool sysDefault);
110  int addRedirectHandler(const std::string& url,const std::string appId,const std::map<std::string,std::string> * pVerbs,bool isSchemeForm,bool sysDefault);
111 
112  int addVerbsToResourceHandler(std::string mimeType,const std::string& appId,const std::map<std::string,std::string>& verbs);
113  int addVerbsToRedirectHandler(const std::string& url,const std::string& appId,const std::map<std::string,std::string>& verbs);
114  int addVerbsDirect(uint32_t index,const std::map<std::string,std::string>& verbs);
115 
116  int swapResourceHandler(std::string mimeType, uint32_t index);
117  int swapRedirectHandler(const std::string& url, uint32_t index);
118 
119  static bool getExtensionFromUrl(const std::string& url,std::string& r_extn);
120  bool getMimeTypeByExtension(std::string extension,std::string& r_mimeType);
121 
122  static uint32_t assignIndex();
123  static uint32_t getLastAssignedIndex();
124  static std::string makePseudoExtensionFromMime(const std::string& mimeType);
125 
126  std::string allTablesAsJsonString();
127  std::string resourceTableAsJsonString();
128  json_object * resourceTableAsJson(); //WARNING: memory allocated; caller must clean
129  json_object * resourceTableAsJsonArray(); //WARNING: memory allocated; caller must clean
130 
131  std::string redirectTableAsJsonString();
132  json_object * redirectTableAsJson(); //WARNING: memory allocated; caller must clean
133  json_object * redirectTableAsJsonArray(); //WARNING: memory allocated; caller must clean
134 
135  std::string extensionMapAsJsonString();
136  json_object * extensionMapAsJson(); //WARNING: memory allocated; caller must clean
137  json_object * extensionMapAsJsonArray(); //WARNING: memory allocated; caller must clean
138 
139  bool saveMimeTable(const std::string& file,std::string& r_err);
140  bool saveMimeTableToActiveFile(std::string& r_err);
141  bool restoreMimeTable(const std::string& file,std::string& r_err);
142  bool restoreMimeTable(json_object * source,std::string& r_err); //a version of restore that takes a read-in version of the file as a json obj.
143  bool clearMimeTable();
144  static void deleteSavedMimeTable();
145 
146  //some utils
147  static int extractVerbsFromHandlerEntryJson(struct json_object * jsonHandlerEntry,std::map<std::string,std::string>& r_verbs);
148  static int extractVerbsFromHandlerNodeEntryJson(struct json_object * jsonHandlerNodeEntry,std::map<std::string,uint32_t>& r_verbs);
149 
150 private:
151 
152  MimeSystem();
153  MimeSystem(const MimeSystem& c) {}
154  MimeSystem& operator=(const MimeSystem& c) { return *this;}
155  virtual ~MimeSystem();
156  void destroy();
157 
158  int populateFromJson(struct json_object * jobj); //useful only for the initial command-resource-handlers.json file reading
159 
161 
162  class VerbCacheEntry {
163  public:
164 
165  VerbCacheEntry() : activeIndex(0) , useCount(0) {}
166  VerbCacheEntry(uint32_t index) : activeIndex(index) , useCount(1) {}
167  VerbCacheEntry(const VerbCacheEntry& c) : activeIndex(c.activeIndex) , useCount(c.useCount) {}
168  VerbCacheEntry& operator=(const VerbCacheEntry& c) {
169  if (this == &c)
170  return *this;
171  activeIndex = c.activeIndex;
172  useCount = c.useCount;
173  return *this;
174  }
175  uint32_t activeIndex;
176  uint32_t useCount;
177  };
178 
179  class RedirectHandlerNode {
180  public:
181  RedirectHandlerNode(const std::string& urlRe, const std::string& appId , bool schemeForm) : m_redirectHandler(urlRe,appId,schemeForm) {
182  m_handlersByIndex[m_redirectHandler.index()] = &m_redirectHandler;
183  }
184  RedirectHandler m_redirectHandler;
185  std::vector<RedirectHandler *> m_alternates;
186 
187  std::map<std::string,VerbCacheEntry> m_verbCache;
188  std::map<uint32_t,RedirectHandler *> m_handlersByIndex;
189 
190  int removePrimary();
191  int removeAppId(const std::string& appId);
192  int swapHandler(uint32_t index);
193 
194  int removeVerb(const std::string& verb,RedirectHandler& handler);
195  int removeAllVerbsOfHandler(RedirectHandler& handler);
196  bool isCurrentVerbHandler(const std::string& verb,RedirectHandler& handler);
197  bool pickRandomVerbHandler(const std::string& verb,uint32_t& r_chosenIndex);
198  bool reassignRandomVerbHandler(const std::string& verb);
199 
200  bool exists(const std::string& urlRe, const std::string& appId) {
201  if (m_redirectHandler.equals(urlRe,appId))
202  return true;
203  for (std::vector<RedirectHandler *>::iterator it=m_alternates.begin();
204  it != m_alternates.end();++it)
205  {
206  if ((*it)->equals(urlRe,appId))
207  return true;
208  }
209  return false;
210  }
211 
212  virtual ~RedirectHandlerNode();
213 
214  std::string toJsonString();
215  struct json_object * toJson(); //WARNING: memory allocated; caller must clean
216  static MimeSystem::RedirectHandlerNode * fromJsonString(const std::string& jsonString);
217  static MimeSystem::RedirectHandlerNode * fromJson(struct json_object * jobj);
218 
219  int fixupVerbCacheTable(struct json_object * jsonHandlerNodeEntry);
220  };
221 
222  class ResourceHandlerNode {
223  public:
224  ResourceHandlerNode(const std::string& ext,
225  const std::string& contentType,
226  const std::string& appId,
227  bool stream=false ) : m_resourceHandler(ext,contentType,appId,stream) {
228  m_handlersByIndex[m_resourceHandler.index()] = &m_resourceHandler;
229  }
230 
231  ResourceHandler m_resourceHandler;
232  std::vector<ResourceHandler *> m_alternates;
233  std::map<std::string,VerbCacheEntry> m_verbCache;
234  std::map<uint32_t,ResourceHandler *> m_handlersByIndex;
235 
236  int removePrimary();
237  int removeAppId(const std::string& appId);
238  int swapHandler(uint32_t index);
239 
240  int removeVerb(const std::string& verb,ResourceHandler& handler);
241  int removeAllVerbsOfHandler(ResourceHandler& handler);
242  bool isCurrentVerbHandler(const std::string& verb,ResourceHandler& handler);
243  bool pickRandomVerbHandler(const std::string& verb,uint32_t& r_chosenIndex);
244  bool reassignRandomVerbHandler(const std::string& verb);
245 
246  bool exists(const std::string& extension,const std::string& appId,const std::string& contentType,bool stream) {
247  if (m_resourceHandler.match(extension,appId,contentType,stream))
248  return true;
249  for (std::vector<ResourceHandler *>::iterator it=m_alternates.begin();
250  it != m_alternates.end();++it)
251  {
252  if ((*it)->match(extension,appId,contentType,stream))
253  return true;
254  }
255  return false;
256  }
257 
258  bool exists(const std::string& appId,const std::string& contentType) {
259  if (m_resourceHandler.match(appId,contentType))
260  return true;
261  for (std::vector<ResourceHandler *>::iterator it=m_alternates.begin();
262  it != m_alternates.end();++it)
263  {
264  if ((*it)->match(appId,contentType))
265  return true;
266  }
267  return false;
268  }
269 
270  virtual ~ResourceHandlerNode();
271 
272  std::string toJsonString();
273  struct json_object * toJson(); //WARNING: memory allocated; caller must clean
274  static MimeSystem::ResourceHandlerNode * fromJsonString(const std::string& jsonString);
275  static MimeSystem::ResourceHandlerNode * fromJson(struct json_object * jobj);
276 
277  int fixupVerbCacheTable(struct json_object * jsonHandlerNodeEntry);
278  };
279 
280  static void reclaimIndex(uint32_t idx);
281 
282  static int addVerbs(const std::map<std::string,std::string>& verbs,ResourceHandlerNode& resourceHandlerNode,ResourceHandler& newHandler);
283  static int addVerbs(const std::map<std::string,std::string>& verbs,RedirectHandlerNode& redirectHandlerNode,RedirectHandler& newHandler);
284 
285 public:
286 
287  //dbg
288  bool dbg_printMimeTables();
289  bool dbg_getResourceTableStrings(std::vector<std::pair<std::string,std::vector<std::string> > >& r_resourceTableStrings);
290  bool dbg_getRedirectTableStrings(std::vector<std::pair<std::string,std::vector<std::string> > >& r_redirectTableStrings);
291  void dbg_printVerbCacheTableForResource(const std::string& mime);
292  void dbg_printVerbCacheTableForRedirect(const std::string& url);
293  void dbg_printVerbCacheTableForScheme(const std::string& url);
294  static void dbg_printVerbCacheTable(const std::map<std::string,VerbCacheEntry> * p_verbCacheTable);
295  static void dbg_printResourceHandlerNode(const ResourceHandlerNode * p_resourceHandlerNode,int level=0);
296  static void dbg_printRedirectHandlerNode(const RedirectHandlerNode * p_redirectHandlerNode,int level=0);
297 
298 private:
299 
300  ResourceHandlerNode * getResourceHandlerNode(const std::string& mimeType);
301  RedirectHandlerNode * getRedirectHandlerNode(const std::string& url);
302  RedirectHandlerNode * getSchemeHandlerNode(const std::string& url);
303 
305 
306  static MimeSystem * s_p_inst;
307 
308  static Mutex s_mutex;
309  Mutex m_mutex;
310 
311  std::map<std::string,MimeSystem::ResourceHandlerNode *> m_resourceHandlerMap;
312  std::map<std::string,MimeSystem::RedirectHandlerNode *> m_redirectHandlerMap;
313 
314  std::map<std::string,std::string> m_extensionToMimeMap;
315  static uint32_t s_genIndex;
316  static uint32_t s_lastAssignedIndex;
317  static std::vector<uint32_t> s_indexRecycler;
318 
319  typedef std::map<std::string,MimeSystem::ResourceHandlerNode *> ResourceMapType;
320  typedef std::map<std::string,MimeSystem::ResourceHandlerNode *>::iterator ResourceMapIterType;
321  typedef std::map<std::string,MimeSystem::RedirectHandlerNode *> RedirectMapType;
322  typedef std::map<std::string,MimeSystem::RedirectHandlerNode *>::iterator RedirectMapIterType;
323  typedef std::map<std::string,MimeSystem::VerbCacheEntry> VerbCacheMapType;
324  typedef std::map<std::string,MimeSystem::VerbCacheEntry>::iterator VerbCacheMapIterType;
325 };
326 
327 #endif /*MIMESYSTEM_H_*/