1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/capability/CapabilityImpl.cc
15 #include "zypp/base/Logger.h"
16 #include "zypp/base/Exception.h"
17 #include "zypp/capability/CapabilityImpl.h"
18 #include "zypp/capability/Capabilities.h"
22 ///////////////////////////////////////////////////////////////////
24 { /////////////////////////////////////////////////////////////////
25 ///////////////////////////////////////////////////////////////////
27 { /////////////////////////////////////////////////////////////////
28 IMPL_PTR_TYPE(CapabilityImpl)
30 ///////////////////////////////////////////////////////////////////
32 // METHOD NAME : CapabilityImpl::CapabilityImpl
35 CapabilityImpl::CapabilityImpl( const Resolvable::Kind & refers_r )
39 ///////////////////////////////////////////////////////////////////
41 // METHOD NAME : CapabilityImpl::capImplOrderLess
44 bool CapabilityImpl::capImplOrderLess( const constPtr & rhs ) const
46 return encode() < rhs->encode();
49 ///////////////////////////////////////////////////////////////////
51 // METHOD NAME : CapabilityImpl::capImplOrderLess
54 std::ostream & CapabilityImpl::dumpOn( std::ostream & str ) const
56 return str << '[' << refers() << "] "
57 << '(' << kind() << ") "
61 /** Assert a valid Resolvable::Kind. */
62 static void assertResKind( const Resolvable::Kind & refers_r )
64 if ( refers_r == Resolvable::Kind() )
65 ZYPP_THROW( Exception("Missing or empty Resolvable::Kind in Capability") );
68 bool isEditionSpec( Rel op_r, const Edition & edition_r )
70 switch ( op_r.inSwitch() )
73 if ( edition_r != Edition::noedition )
74 WAR << "Operator " << op_r << " causes Edition "
75 << edition_r << " to be ignored." << endl;
80 ZYPP_THROW( Exception("Operator NONE is not allowed in Capability") );
92 // SHOULD NOT GET HERE
93 ZYPP_THROW( Exception("Unknown Operator NONE is not allowed in Capability") );
94 return false; // not reached
97 bool isFileSpec( const std::string & name_r )
99 return *name_r.c_str() == '/';
102 bool isSplitSpec( const std::string & name_r )
104 return name_r.find( ":/" ) != std::string::npos;
107 bool isHalSpec( const std::string & name_r )
109 return name_r.substr(0,4) == "hal(";
112 bool isModaliasSpec( const std::string & name_r )
114 return name_r.substr(0,9) == "modalias(";
117 bool isFilesystemSpec( const std::string & name_r )
119 return name_r.substr(0,11) == "filesystem(";
122 CapabilityImpl::Ptr buildFile( const Resolvable::Kind & refers_r,
123 const std::string & name_r )
125 // NullCap check first:
126 if ( name_r.empty() )
128 // Singleton, so no need to put it into _uset !?
129 return capability::NullCap::instance();
132 assertResKind( refers_r );
134 return new capability::FileCap( refers_r, name_r );
137 CapabilityImpl::Ptr buildNamed( const Resolvable::Kind & refers_r,
138 const std::string & name_r )
140 // NullCap check first:
141 if ( name_r.empty() )
143 // Singleton, so no need to put it into _uset !?
144 return capability::NullCap::instance();
147 assertResKind( refers_r );
149 // file: /absolute/path
150 if ( isFileSpec( name_r ) )
152 return new capability::FileCap( refers_r, name_r );
154 if ( isFilesystemSpec( name_r ) )
156 return buildFilesystem( refers_r, name_r );
159 //split: name:/absolute/path
160 std::vector<std::string> what;
161 if (str::split( name_r, std::back_inserter(what), ":") >= 2)
163 return new capability::SplitCap( refers_r, what[0], what[1] );
167 return new capability::NamedCap( refers_r, name_r );
170 CapabilityImpl::Ptr buildVersioned( const Resolvable::Kind & refers_r,
171 const std::string & name_r,
173 const Edition & edition_r )
175 if ( isEditionSpec( op_r, edition_r ) )
177 assertResKind( refers_r );
179 // build a VersionedCap
180 return new capability::VersionedCap( refers_r, name_r, op_r, edition_r );
185 return buildNamed( refers_r, name_r );
188 CapabilityImpl::Ptr buildHal( const Resolvable::Kind & refers_r,
189 const std::string & name_r,
191 const std::string & value_r )
193 if ( op_r != Rel::ANY )
195 ZYPP_THROW( Exception("Unsupported kind of Hal Capability '" + op_r.asString() + "'") );
198 //split: hal(name) [op string]
199 std::vector<std::string> what;
200 if (str::split( name_r, std::back_inserter(what), ")"))
202 // Hal always refers to 'System' kind of Resolvable.
203 return new capability::HalCap( ResTraits<SystemResObject>::kind,
204 what[0].substr(strlen("hal(")) );
207 ZYPP_THROW( Exception("Unsupported kind of Hal Capability '" + name_r + "'") );
208 return NULL; // make gcc happy
211 CapabilityImpl::Ptr buildModalias( const Resolvable::Kind & refers_r,
212 const std::string & name_r,
214 const std::string & value_r )
216 if ( op_r != Rel::ANY )
218 ZYPP_THROW( Exception("Unsupported kind of Modalias Capability '" + op_r.asString() + "'") );
221 //split: modalias(name) [op string]
222 std::vector<std::string> what;
223 if (str::split( name_r, std::back_inserter(what), ")"))
225 // Modalias always refers to 'System' kind of Resolvable
226 return new capability::ModaliasCap( ResTraits<SystemResObject>::kind,
227 what[0].substr(strlen("modalias(")));
230 ZYPP_THROW( Exception("Unsupported kind of Modalias Capability'" + name_r + "'") );
231 return NULL; // make gcc happy
234 /******************************************************************
236 ** FUNCTION NAME : buildFilesystem
237 ** FUNCTION TYPE : CapabilityImpl::Ptr
239 CapabilityImpl::Ptr buildFilesystem( const Resolvable::Kind & refers_r,
240 const std::string & name_r )
242 //split: filesystem(name) [op string]
243 std::vector<std::string> what;
244 if (str::split( name_r, std::back_inserter(what), ")"))
246 // Filesystem always refers to 'System' kind of Resolvable
247 return new capability::FilesystemCap( ResTraits<SystemResObject>::kind,
248 what[0].substr(strlen("filesystem(")) );
251 ZYPP_THROW( Exception("Unsupported kind of Filesystem Capability'" + name_r + "'") );
252 return NULL; // make gcc happy
256 CapabilityImpl::Ptr parse( const Resolvable::Kind & refers_r,
257 const std::string & strval_r )
260 if ( isHalSpec( strval_r ) )
262 return buildHal( refers_r, strval_r );
264 if ( isModaliasSpec( strval_r ) )
266 return buildModalias( refers_r, strval_r );
268 if ( isFilesystemSpec( strval_r ) )
270 return buildFilesystem( refers_r, strval_r );
272 if ( isFileSpec( strval_r ) )
274 return buildFile( refers_r, strval_r );
277 // strval_r has at least two words which could make 'op edition'?
278 std::vector<std::string> what;
279 if (str::split( strval_r, std::back_inserter(what)) >= 2)
286 edition = Edition(what[2]);
288 catch ( Exception & excpt )
290 // So they don't make valid 'op edition'
291 ZYPP_CAUGHT( excpt );
292 DBG << "Trying named cap for: " << strval_r << endl;
293 // See whether it makes a named cap.
294 return buildNamed( refers_r, strval_r );
297 // Valid 'op edition'
298 return buildVersioned( refers_r,
299 what[0], op, edition );
302 // not a VersionedCap
303 return buildNamed( refers_r, strval_r );
305 catch ( Exception & excpt )
307 ZYPP_RETHROW( excpt );
308 return NULL; // not reached
312 CapabilityImpl::Ptr parse( const Resolvable::Kind & refers_r,
313 const std::string & name_r,
314 const std::string & op_r,
315 const std::string & edition_r )
318 if ( isHalSpec( name_r ) )
320 return buildHal( refers_r, name_r, Rel(op_r), edition_r );
322 if ( isModaliasSpec( name_r ) )
324 return buildModalias( refers_r, name_r, Rel(op_r), edition_r );
326 // Try creating Rel and Edition, then parse
327 return parse( refers_r, name_r, Rel(op_r), Edition(edition_r) );
329 catch ( Exception & excpt )
331 ZYPP_RETHROW( excpt );
332 return NULL; // not reached
335 ///////////////////////////////////////////////////////////////////
337 // METHOD NAME : CapFactory::parse
338 // METHOD TYPE : Capability
340 CapabilityImpl::Ptr parse( const Resolvable::Kind & refers_r,
341 const std::string & name_r,
343 const Edition & edition_r )
346 if ( isHalSpec( name_r ) )
348 return buildHal( refers_r, name_r, op_r, edition_r.asString() );
350 if ( isModaliasSpec( name_r ) )
352 return buildModalias( refers_r, name_r, op_r, edition_r.asString() );
354 return buildVersioned( refers_r, name_r, op_r, edition_r );
356 catch ( Exception & excpt )
358 ZYPP_RETHROW( excpt );
359 return NULL; // not reached
362 ///////////////////////////////////////////////////////////////////
364 /////////////////////////////////////////////////////////////////
365 } // namespace capability
366 ///////////////////////////////////////////////////////////////////
367 /////////////////////////////////////////////////////////////////
369 ///////////////////////////////////////////////////////////////////