## Copyright 2014 Chef Software, Inc.## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.#require"cgi"require"json"require"uri"moduleArtifactoryclassResource::Baseclass<<self## @macro attribute# @method $1# Return this object's +$1+## @return [Object]### @method $1=(value)# Set this object's +$1+## @param [Object] value# the value to set for +$1+# @param [Object] default# the default value for this attribute## @method $1?# Determines if the +$1+ value exists and is truthy## @return [Boolean]#defattribute(key,default=nil)key=key.to_symunlesskey.is_a?(Symbol)# Set this attribute in the top-level hashattributes[key]=nildefine_method(key)dovalue=attributes[key]returnvalueunlessvalue.nil?ifdefault.nil?valueelsifdefault.is_a?(Proc)default.callelsedefaultendenddefine_method("#{key}?")do!!attributes[key]enddefine_method("#{key}=")do|value|set(key,value)endend## The list of attributes defined by this class.## @return [Array<Symbol>]#defattributes@attributes||={}end## Determine if this class has a given attribute.## @param [#to_sym] key# the key to check as an attribute## @return [true, false]#defhas_attribute?(key)attributes.has_key?(key.to_sym)end## Construct a new object from the given URL.## @param [String] url# the URL to find the user from# @param [Hash] options# the list of options## @option options [Artifactory::Client] :client# the client object to make the request with## @return [~Resource::Base]#deffrom_url(url,options={})# Parse the URL and only use the path so the configured# endpoint/proxy/SSL settings are used in the GET request.path=URI.parse(url_safe(url)).pathclient=extract_client!(options)# If the endpoint contains a path part, we must remove the# endpoint path part from path, because the client uses# endpoint + path as its full URI.endpoint_path=URI.parse(client.endpoint).pathpath.slice!(endpoint_path)from_hash(client.get(path),client: client)end## List all the child text elements in the Artifactory configuration file# of a node matching the specified xpath## @param [String] xpath# xpath expression for the parent element whose children are to be listed## @param [REXML] config# Artifactory config as an REXML file## @param [Hash] options# the list of options#deflist_from_config(xpath,config,options={})REXML::XPath.match(config,xpath).mapdo|r|hash={}r.each_element_with_textdo|l|hash[l.name]=l.get_textendfrom_hash(hash,options)endend## Find the text elements matching a giving xpath## @param [String] xpath# xpath expression## @param [REXML] config# Artifactory configuration file as an REXML doc## @param [Hash] options# the list of options#deffind_from_config(xpath,config,options={})name_node=REXML::XPath.match(config,xpath)returnnilifname_node.empty?properties={}name_node[0].parent.each_element_with_textdo|e|properties[e.name]=Util.to_type(e.text)endfrom_hash(properties,options)end## Construct a new object from the hash.## @param [Hash] hash# the hash to create the object with# @param [Hash] options# the list options## @option options [Artifactory::Client] :client# the client object to make the request with## @return [~Resource::Base]#deffrom_hash(hash,options={})instance=newinstance.client=extract_client!(options)hash.inject(instance)do|instance,(key,value)|method=:"#{Util.underscore(key)}="ifinstance.respond_to?(method)instance.send(method,value)endinstanceendend## Get the client (connection) object from the given options. If the# +:client+ key is preset in the hash, it is assumed to contain the# connection object to use for the request. If the +:client+ key is not# present, the default {Artifactory.client} is used.## Warning, the value of {Artifactory.client} is **not** threadsafe! If# multiple threads or processes are modifying the connection information,# the same request _could_ use a different client object. If you use the# {Artifactory::Client} proxy methods, this is handled for you.## Warning, this method will **remove** the +:client+ key from the hash if# it exists.## @param [Hash] options# the list of options passed to the method## @option options [Artifactory::Client] :client# the client object to use for requests#defextract_client!(options)options.delete(:client)||Artifactory.clientend## Format the repos list from the given options. This method will modify# the given Hash parameter!## Warning, this method will modify the given hash if it exists.## @param [Hash] options# the list of options to extract the repos from#defformat_repos!(options)returnoptionsifoptions[:repos].nil?||options[:repos].empty?options[:repos]=Array(options[:repos]).compact.join(",")optionsend## Generate a URL-safe string from the given value.## @param [#to_s] value# the value to sanitize## @return [String]# the URL-safe version of the string#defurl_safe(value)URI.escape(URI.unescape(value.to_s))endendattribute:client,->{Artifactory.client}## Create a new instance#definitialize(attributes={})attributes.eachdo|key,value|set(key,value)endend## The list of attributes for this resource.## @return [hash]#defattributes@attributes||=self.class.attributes.dupend## Set a given attribute on this resource.## @param [#to_sym] key# the attribute to set# @param [Object] value# the value to set## @return [Object]# the set value#defset(key,value)attributes[key.to_sym]=valueend# @see Resource::Base.extract_client!defextract_client!(options)self.class.extract_client!(options)end# @see Resource::Base.format_repos!defformat_repos!(options)self.class.format_repos!(options)end# @see Resource::Base.url_safedefurl_safe(value)self.class.url_safe(value)end## The hash representation## @example An example hash response# { 'key' => 'local-repo1', 'includesPattern' => '**/*' }## @return [Hash]#defto_hashattributes.inject({})do|hash,(key,value)|unlessResource::Base.has_attribute?(key)hash[Util.camelize(key,true)]=send(key.to_sym)endhashendend## The JSON representation of this object.## @see Artifactory::Resource::Base#to_json## @return [String]#defto_jsonJSON.fast_generate(to_hash)end## Create CGI-escaped string from matrix properties## @see http://bit.ly/1qeVYQl#defto_matrix_properties(hash={})properties=hash.mapdo|k,v|key=CGI.escape(k.to_s)value=CGI.escape(v.to_s)"#{key}=#{value}"endifproperties.empty?nilelse";#{properties.join(';')}"endend## Create URI-escaped querystring parameters## @see http://bit.ly/1qeVYQl#defto_query_string_parameters(hash={})properties=hash.mapdo|k,v|key=URI.escape(k.to_s)value=URI.escape(v.to_s)"#{key}=#{value}"endifproperties.empty?nilelseproperties.join("&")endend# @privatedefto_s"#<#{short_classname}>"end# @privatedefinspectlist=attributes.collectdo|key,value|unlessResource::Base.has_attribute?(key)"#{key}: #{value.inspect}"endend.compact"#<#{short_classname}#{list.join(', ')}>"endprivatedefshort_classname@short_classname||=self.class.name.split("::").lastendendend