metadata.scala

来自「JAVA 语言的函数式编程扩展」· SCALA 代码 · 共 288 行

SCALA
288
字号
/*                     __                                               *\**     ________ ___   / /  ___     Scala API                            ****    / __/ __// _ | / /  / _ |    (c) 2003-2007, LAMP/EPFL             ****  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **** /____/\___/_/ |_/____/_/ | |                                         ****                          |/                                          **\*                                                                      */// $Id: MetaData.scala 14027 2008-02-16 18:38:12Z emir $package scala.xml/** * Copyright 2008 Google Inc. All Rights Reserved. * @author Burak Emir <bqe@google.com> */object MetaData {  /**    * appends all attributes from new_tail to attribs, without attempting to detect   * or remove duplicates. The method guarantees that all attributes from attribs come before   * the attributes in new_tail, but does not guarantee to preserve the relative order of attribs.   * Duplicates can be removed with normalize.   */  def concatenate(attribs: MetaData, new_tail: MetaData): MetaData =    if (attribs eq Null)      new_tail    else      concatenate(attribs.next, attribs.copy(new_tail)) // tail-recursive  /**   * returns normalized MetaData, with all duplicates removed and namespace prefixes resolved to   *  namespace URIs via the given scope.   */  def normalize(attribs: MetaData, scope: NamespaceBinding): MetaData = {    import collection.mutable.HashSet    def iterate(md: MetaData, normalized_attribs: MetaData, map: HashSet[String]): MetaData = {      if (md eq Null)        normalized_attribs      else {        val universal_key = getUniversalKey(md, scope)        if (map.contains(universal_key))          iterate(md.next, normalized_attribs, map)        else {          map += universal_key          iterate(md.next, md.copy(normalized_attribs), map)        }       }    }    iterate(attribs, Null, new HashSet[String])  }   /**   * returns key if md is unprefixed, pre+key is md is prefixed   */  def getUniversalKey(attrib: MetaData, scope: NamespaceBinding) = attrib match {    case prefixed: PrefixedAttribute     => scope.getURI(prefixed.pre) + prefixed.key    case unprefixed: UnprefixedAttribute => unprefixed.key  }  /**   *  returns MetaData with attributes updated from given MetaData   */  def update(attribs: MetaData, scope: NamespaceBinding, updates: MetaData): MetaData =    normalize(concatenate(updates, attribs), scope)}/** <p> *    This class represents an attribute and at the same time a linked list of attributes. *    Every instance of this class is either an instance of UnprefixedAttribute <code>key,value</code> *    or an instance of PrefixedAttribute <code>namespace_prefix,key,value</code> or Null, the empty *    attribute list. Namespace URIs are obtained by using the namespace scope of the element owning *    this attribute (see <code>getNamespace</code>) * </p> * * Copyright 2008 Google Inc. All Rights Reserved. * @author Burak Emir <bqe@google.com> */@serializableabstract class MetaData extends Collection[MetaData] {  /** updates this MetaData with the MetaData given as argument. All attributes that occur in updates   *  are part of the resulting MetaData. If an unprefixed attribute occurs in both this instance and    *  updates, only the one in updates is part of the result (avoiding duplicates). However, for    *  prefixed attributes no duplicate-detection is attempted, the method    *  append(updates: MetaData, scope:NamespaceBinding) should be used instead.   *   *  @param updates MetaData with new attributes and updated attributes   *  @return a new MetaData instance that contains the combined attributes of this and updates   */  def append(updates: MetaData): MetaData =    MetaData.update(this, TopScope, updates)  /** updates this MetaData with the MetaData given as argument. All attributes that occur in updates   *  are part of the resulting MetaData. If an attribute occurs in both this instance and    *  updates, only the one in updates is part of the result (avoiding duplicates). For prefixed   *  attributes, namespaces are resolved using the given scope.   *   *  @param updates MetaData with new and updated attributes   *  @return a new MetaData instance that contains old, new and updated attributes   */  def append(updates: MetaData, scope: NamespaceBinding): MetaData =    MetaData.update(this, scope, updates)  /**   * Gets value of unqualified (unprefixed) attribute with given key, null if not found   *   * @param  key   * @return value as Seq[Node] if key is found, null otherwise   */  def apply(key: String): Seq[Node]  /** convenience method, same as <code>apply(namespace, owner.scope, key)</code>.   *   *  @param namespace_uri namespace uri of key   *  @param owner the element owning this attribute list   *  @param key   the attribute key   *  @return          ...   */  final def apply(namespace_uri: String, owner: Node, key: String): Seq[Node] =    apply(namespace_uri, owner.scope, key)  /**   * Gets value of prefixed attribute with given key and namespace, null if not found   *   * @param  namespace_uri namespace uri of key   * @param  scp a namespace scp (usually of the element owning this attribute list)   * @param  key to be looked fore   * @return value as Seq[Node] if key is found, null otherwise   */  def apply(namespace_uri:String, scp:NamespaceBinding, k:String): Seq[Node]  /**   *  @param m ...   *  @return  <code>true</code> iff ...   */  def containedIn1(m: MetaData): Boolean =    m.equals1(this) || containedIn1(m.next)  /** returns a copy of this MetaData item with next field set to argument.   *   *  @param next ...   *  @return     ...   */  def copy(next: MetaData): MetaData  /** if owner is the element of this metadata item, returns namespace */  def getNamespace(owner: Node): String   def hasNext = (Null != next)  def length: Int = length(0)  def length(i: Int): Int = next.length(i + 1)  def isPrefixed: Boolean  /** deep equals method */  override def equals(that: Any) =    that match {      case m: MetaData =>        var res = (this.length == m.length) && (this.hashCode() == m.hashCode())        val it = this.elements        while (res && it.hasNext) { res = it.next.containedIn1(m) }        res      case _ =>        false    }  /** returns an iterator on attributes */  def elements: Iterator[MetaData] = new Iterator[MetaData] {    var x: MetaData = MetaData.this    def hasNext = Null != x    def next = {      val y = x      x = x.next      y    }  }  def size : Int = 1 + {    if (Null == next) 0 else next.size  }  /** shallow equals method */  def equals1(that: MetaData): Boolean  /** filters this sequence of meta data */  override def filter(f: MetaData => Boolean): MetaData = {    if (f(this)) copy(next filter f) else next filter f  }  /** returns key of this MetaData item */  def key: String  /** returns value of this MetaData item */  def value: Seq[Node]  /** maps this sequence of meta data */  def map(f: MetaData => Text): List[Text] = f(this)::(next map f)  /** returns Null or the next MetaData item */  def next: MetaData  /**   * Gets value of unqualified (unprefixed) attribute with given key, None if not found   *   * @param  key   * @return value in Some(Seq[Node]) if key is found, None otherwise   */  final def get(key: String): Option[Seq[Node]] = apply(key) match {    case null => None    case x    => Some(x)  }  /** same as get(uri, owner.scope, key) */  final def get(uri: String, owner: Node, key: String): Option[Seq[Node]] =    get(uri, owner.scope, key)  /** gets value of qualified (prefixed) attribute with given key.   *   * @param  uri namespace of key   * @param  scope a namespace scp (usually of the element owning this attribute list)   * @param  key to be looked fore   * @return value as Some[Seq[Node]] if key is found, None otherwise   */  final def get(uri: String, scope: NamespaceBinding, key: String): Option[Seq[Node]] =    apply(uri, scope, key) match {      case null => None      case x    => Some(x)    }  override def hashCode(): Int  def toString1(): String = {    val sb = new StringBuilder()    toString1(sb)    sb.toString()  }  //appends string representations of single attribute to StringBuilder  def toString1(sb:StringBuilder): Unit  override def toString(): String = {    val sb = new StringBuilder()    toString(sb)    sb.toString()  }  def toString(sb: StringBuilder): StringBuilder = {    sb.append(' ')    toString1(sb)    next.toString(sb)  }  /**   *  @param scope ...   *  @return      <code>true</code> iff ...   */  def wellformed(scope: NamespaceBinding): Boolean  /**   *  @param key ...   *  @return    ...   */  def remove(key:String): MetaData  /**   *  @param namespace ...   *  @param scope     ...   *  @param key       ...   *  @return          ...   */  def remove(namespace: String, scope: NamespaceBinding, key: String): MetaData  /**   *  @param namespace ...   *  @param owner     ...   *  @param key       ...   *  @return          ...   */  final def remove(namespace: String, owner: Node, key: String): MetaData =    remove(namespace, owner.scope, key)}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?