uri_resolvers.h
Go to the documentation of this file.
00001 /*
00002  * Copyright 2006-2011 The FLWOR Foundation.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  * 
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 #ifndef ZORBA_URI_RESOLVERS_API_H
00017 #define ZORBA_URI_RESOLVERS_API_H
00018 
00019 #include <istream>
00020 #include <vector>
00021 #include <map>
00022 
00023 #include <zorba/config.h>
00024 #include <zorba/api_shared_types.h>
00025 #include <zorba/item.h>
00026 #include <zorba/zorba_string.h>
00027 #include <zorba/streams.h>
00028 #include <zorba/locale.h>
00029 #include <zorba/internal/unique_ptr.h>
00030 #include <zorba/internal/ztd.h>
00031 
00032 /**
00033  * @file uri_resolvers.h
00034  * @brief This header file defines all uri resolvers.
00035  *
00036  * %Zorba has a very flexible uri resolver mechanism.
00037  *
00038  * QQQ Complete documentation
00039  * QQQ file should be renamed uri_resolver.h
00040  */
00041 
00042 namespace zorba {
00043 
00044 /**
00045  * @brief The class representing the result of URL resolution.
00046  *
00047  * This class is the final output of the URI resolution process. All
00048  * URL resolvers return results using subclasses of this class.
00049  */
00050 class ZORBA_DLL_PUBLIC Resource
00051 {
00052 public:
00053   typedef std::unique_ptr<Resource,internal::ztd::destroy_delete<Resource> > ptr;
00054 
00055   virtual ~Resource() = 0;
00056 
00057   /**
00058    * @brief Destroy/clean up this Resource.
00059    *
00060    * Zorba will call this method when it no longer needs the Resource. It
00061    * is the responsibility of subclasses to clean up appropriate when
00062    * this method is called, including calling "delete this" if the Resource
00063    * was allocated with "new".
00064    */
00065   virtual void destroy() const = 0;
00066 };
00067 
00068 /**
00069  * @brief Concrete Resource subclass representing access to an entity
00070  * via a stream.
00071  */
00072 class ZORBA_DLL_PUBLIC StreamResource : public Resource
00073 {
00074 public:
00075 
00076   /**
00077    * @brief Public factory method from istream.
00078    *
00079    * The Resource object will take memory ownership of the istream. Zorba will
00080    * pass it to aStreamReleaser when it is no longer needed, so that the
00081    * original client may delete it.
00082    * @param aStream An istream whence to read the string's content.
00083    * @param aStreamReleaser A function pointer which is invoked once
00084    *        the StreamResource is destroyed. Normally this function will delete
00085    *        the std::istream object passed to it.
00086    */
00087   static StreamResource* create(std::istream* aStream,
00088                                 StreamReleaser aStreamReleaser);
00089   
00090   /**
00091    * @brief Retrieve the istream associated with this Resource.
00092    */
00093   virtual std::istream* getStream() = 0;
00094 
00095   /**
00096    * @brief Retrieve the stream-releaser function.
00097    */
00098   virtual StreamReleaser getStreamReleaser() = 0;
00099 
00100   virtual ~StreamResource() = 0;
00101 };
00102 
00103 /**
00104  * @brief The class containing data which may be of use to URIMappers
00105  * and URLResolvers when mapping/resolving a URI.
00106  *
00107  * This base class specifies the kind of entity for which this URI is being
00108  * resolved - for instance, a schema URI or a module URI. Subclasses of
00109  * this class will provide additional data for specific kinds of entities.
00110  */
00111 class ZORBA_DLL_PUBLIC EntityData
00112 {
00113 public:
00114   /**
00115    * @brief enum listing the kinds of entities that may be represented
00116    * by URIs, and hence may be looked up via the URI resolution
00117    * mechanism.
00118    */
00119   enum Kind {
00120     SCHEMA,
00121     MODULE,
00122     THESAURUS,
00123     STOP_WORDS,
00124     COLLECTION,
00125     DOCUMENT
00126   };
00127 
00128   /**
00129    * @brief Return the Kind of Entity for which this URI is being resolved.
00130    */
00131   virtual Kind getKind() const = 0;
00132 
00133   virtual ~EntityData() = 0;
00134 };
00135 
00136 /**
00137  * @brief Interface for URL resolving.
00138  *
00139  * Subclass this to provide a URL resolver to the method
00140  * StaticContext::addURLResolver().
00141  */
00142 class ZORBA_DLL_PUBLIC URLResolver
00143 {
00144   public:
00145 
00146   URLResolver();
00147   virtual ~URLResolver();
00148 
00149   /**
00150    * @brief Transforms an input URL into a Resource.
00151    *
00152    * The "aEntityData" parameter informs the URLResolver what kind of
00153    * entity is being referenced by the URL. URLResolvers may choose to
00154    * make use of this information to alter their behaviour.
00155    * URLResolvers must ensure that they return a concrete subclass of
00156    * Resource which is compatible with the entity kind being resolved.
00157    *
00158    * Implementers of this method should do nothing if they do not know
00159    * how to resolve the URL.  They should create and return a Resource
00160    * if they were successfully able to resolve the URL.
00161    *
00162    * Implementers may throw any exception if they believe that they
00163    * are canonical for the URL and yet had some error arise attempting
00164    * to resolve it.  Note that because there may be several possible
00165    * URLs attempted, Zorba will catch any exceptions thrown and
00166    * continue until all all URLs have failed. Zorba will not re-throw
00167    * any of these exceptions directly. However, if the exception
00168    * thrown extends std::exception, Zorba will make efforts to ensure
00169    * that its error message is included in the exception which is
00170    * ultimately thrown. For any other thrown objects, only the fact
00171    * that an exception occurred will be remembered; the exception
00172    * object itself will be discarded.
00173    *
00174    * In any case, if they create a Resource, Zorba will take memory
00175    * ownership of the Resource and delete it when it is no longer
00176    * needed.
00177    */
00178   virtual Resource* resolveURL(const zorba::String& aUrl,
00179     EntityData const* aEntityData) = 0;
00180 };
00181 
00182 /**
00183  * @brief Interface for URI mapping.
00184  *
00185  * Subclass this to provide a URI mapper to the method
00186  * StaticContext::addURIMapper().
00187  */
00188 class ZORBA_DLL_PUBLIC URIMapper
00189 {
00190   public:
00191 
00192   URIMapper();
00193   virtual ~URIMapper();
00194 
00195   /**
00196    * @brief Transform an input URI into a set of output URIs.
00197    *
00198    * The "aEntityData" parameter informs the URIMapper what kind of
00199    * entity is being referenced by URI. URIMappers may choose to make
00200    * use of this information to alter their behaviour.
00201    *
00202    * Implementers of this method should provide output URIs by adding
00203    * them to the oUris output parameter, using the push_back()
00204    * method. They should not otherwise view or manipulate this vector.
00205    *
00206    * If a URIMapper does not wish to provide any output URIs for the
00207    * given input URI, they should simply do nothing and return. In
00208    * this case, Zorba will continue with the original, unmapped URI.
00209    */
00210   virtual void mapURI(const zorba::String aUri,
00211     EntityData const* aEntityData, std::vector<zorba::String>& oUris)
00212     = 0;
00213 
00214   /**
00215    * @brief enum defining legal return values for mapperKind().
00216    */
00217   enum Kind {
00218     COMPONENT,
00219     CANDIDATE
00220   };
00221 
00222   /**
00223    * @brief Declare whether this is a "component" or "candidate" URI
00224    * mapper.
00225    *
00226    * Zorba supports two different kinds of URI mapping. The first,
00227    * "component URI mapping", is to allow mapping from an input URI to
00228    * a set of URIs which, taken together, comprise the entire entity
00229    * to be resolved. This is currently only supported for module
00230    * import, where it can be used to load a module which is physically
00231    * stored in multiple library module files.
00232    *
00233    * "Candidate URI mapping" is to allow mapping from an input URI to
00234    * a set or URIs which are *potential* identifiers of the entity
00235    * being resolved. Each of these URIs will be treated to any
00236    * subsequent URI mappers, and then treated as URLs and passed in
00237    * turn to all registered URLResolvers. This type of URI mapping is
00238    * supported for all uses of URIs in Zorba. It can be used for
00239    * example to redirect http: URIs to locally-cached file: URLs, or
00240    * to provide several alternative locations for a given resource.
00241    *
00242    * If you do not override this method, the default is "candidate".
00243    */
00244   virtual Kind mapperKind();
00245 
00246   /**
00247    * @brief Constant indicating that Zorba should deny access to the
00248    * given URI.
00249    *
00250    * If any kind of URIMapper returns this value at any point in the
00251    * vector of URIs, Zorba will cause the resolution of this URI to be
00252    * denied with an error.  This can be used, for example, to suppress
00253    * importing particular modules by URI.
00254    */
00255   const static zorba::String DENY_ACCESS;
00256 };
00257 
00258 
00259 /**
00260  * Convenience implementation of a mapper that maps URIs to other
00261  * single URIs. Will only map for one specific Entity Kind.
00262  */
00263 class ZORBA_DLL_PUBLIC OneToOneURIMapper : public URIMapper {
00264 
00265 public:
00266 
00267   /**
00268    * Constructor. Specify the Entity Kind you wish to map. Optionally,
00269    * specify whether this should be a CANDIDATE or COMPONENT mapper;
00270    * default is CANDIDATE.
00271    * QQQ COMPONENT is no longer used; delete?
00272    */
00273   OneToOneURIMapper(EntityData::Kind aEntityKind,
00274                     URIMapper::Kind aMapperKind = URIMapper::CANDIDATE);
00275 
00276   /**
00277    * Add a mapping from a given URI to another URI.
00278    */
00279   void
00280   addMapping(const String& aUri, const String& aMappedUri);
00281 
00282   virtual Kind mapperKind();
00283 
00284   virtual void mapURI(const zorba::String aUri,
00285     EntityData const* aEntityData, std::vector<zorba::String>& oUris);
00286 
00287 private:
00288 
00289   EntityData::Kind const theEntityKind;
00290   URIMapper::Kind const theMapperKind;
00291   typedef std::map<String, String> Mapping_t;
00292   typedef Mapping_t::const_iterator          MappingIter_t;
00293   Mapping_t theMappings;
00294 };
00295 
00296 } /* namespace zorba */
00297 
00298 #endif
00299 /* vim:set et sw=2 ts=2: */
blog comments powered by Disqus