alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Lucene example source code file (AttributeImpl.java)

This example Lucene source code file (AttributeImpl.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Lucene tags/keywords

attribute, attribute, attributeimpl, class, deprecated, deprecated, field, io, object, object, override, reflection, runtimeexception, string, string, stringbuilder, util

The Lucene AttributeImpl.java source code

package org.apache.lucene.util;

/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.lang.ref.WeakReference;
import java.util.LinkedList;

import org.apache.lucene.analysis.tokenattributes.CharTermAttributeImpl; // deprecated

/**
 * Base class for Attributes that can be added to a 
 * {@link org.apache.lucene.util.AttributeSource}.
 * <p>
 * Attributes are used to add data in a dynamic, yet type-safe way to a source
 * of usually streamed objects, e. g. a {@link org.apache.lucene.analysis.TokenStream}.
 */
public abstract class AttributeImpl implements Cloneable, Serializable, Attribute {  
  /**
   * Clears the values in this AttributeImpl and resets it to its 
   * default value. If this implementation implements more than one Attribute interface
   * it clears all.
   */
  public abstract void clear();
  
  /**
   * Returns a string representation of the object. In general, the {@code toString} method
   * returns a string that "textually represents" this object.
   *
   * <p>WARNING: For backwards compatibility this method is implemented as
   * {@code return reflectAsString(false)}. In Lucene 4.0 this default implementation
   * will be removed. The reason for this is the problem of
   * {@link CharTermAttributeImpl#toString} that must return a string representation
   * of the term's char sequence.
   *
   * <p>It is recommeneded to use {@link #reflectAsString} or {@link #reflectWith}
   * to get a well-defined output of AttributeImpl's internals.
   */
  // TODO: @deprecated remove this method in 4.0
  @Override
  public String toString() {
    return reflectAsString(false);
  }
  
  /**
   * This method returns the current attribute values as a string in the following format
   * by calling the {@link #reflectWith(AttributeReflector)} method:
   * 
   * <ul>
   * <li>iff {@code prependAttClass=true}: {@code "AttributeClass#key=value,AttributeClass#key=value"}
   * <li>iff {@code prependAttClass=false}: {@code "key=value,key=value"}
   * </ul>
   *
   * @see #reflectWith(AttributeReflector)
   * @see #toString()
   */
  public final String reflectAsString(final boolean prependAttClass) {
    final StringBuilder buffer = new StringBuilder();
    reflectWith(new AttributeReflector() {
      public void reflect(Class<? extends Attribute> attClass, String key, Object value) {
        if (buffer.length() > 0) {
          buffer.append(',');
        }
        if (prependAttClass) {
          buffer.append(attClass.getName()).append('#');
        }
        buffer.append(key).append('=').append((value == null) ? "null" : value);
      }
    });
    return buffer.toString();
  }
  
  /**
   * @deprecated this will be removed in Lucene 4.0
   */
  @Deprecated
  private static final VirtualMethod<AttributeImpl> toStringMethod =
    new VirtualMethod<AttributeImpl>(AttributeImpl.class, "toString");
    
  /**
   * When {@code true} (default), if a subclass overrides {@link #toString()},
   * its output is parsed by {@link #reflectWith} and used for attribute reflection.
   * This is added to enable attribute implementations from Lucene 2.9 or 3.0 to
   * work correctly with reflection.
   * @deprecated this will be removed in Lucene 4.0.
   */
  @Deprecated
  protected boolean enableBackwards = true;

  /**
   * @deprecated this will be removed in Lucene 4.0
   */
  @Deprecated
  private boolean assertExternalClass(Class<? extends AttributeImpl> clazz) {
    final String name = clazz.getName();
    return (!name.startsWith("org.apache.lucene.") && !name.startsWith("org.apache.solr."))
      || name.equals("org.apache.lucene.util.TestAttributeSource$TestAttributeImpl");
  }

  /**
   * This method is for introspection of attributes, it should simply
   * add the key/values this attribute holds to the given {@link AttributeReflector}.
   *
   * <p>The default implementation calls {@link AttributeReflector#reflect} for all
   * non-static fields from the implementing class, using the field name as key
   * and the field value as value. The Attribute class is also determined by reflection.
   * Please note that the default implementation can only handle single-Attribute
   * implementations.
   *
   * <p>Custom implementations look like this (e.g. for a combined attribute implementation):
   * <pre>
   *   public void reflectWith(AttributeReflector reflector) {
   *     reflector.reflect(CharTermAttribute.class, "term", term());
   *     reflector.reflect(PositionIncrementAttribute.class, "positionIncrement", getPositionIncrement());
   *   }
   * </pre>
   *
   * <p>If you implement this method, make sure that for each invocation, the same set of {@link Attribute}
   * interfaces and keys are passed to {@link AttributeReflector#reflect} in the same order, but possibly
   * different values. So don't automatically exclude e.g. {@code null} properties!
   *
   * @see #reflectAsString(boolean)
   */
  public void reflectWith(AttributeReflector reflector) {
    final Class<? extends AttributeImpl> clazz = this.getClass();
    final LinkedList<WeakReference> interfaces = AttributeSource.getAttributeInterfaces(clazz);
    if (interfaces.size() != 1) {
      throw new UnsupportedOperationException(clazz.getName() +
        " implements more than one Attribute interface, the default reflectWith() implementation cannot handle this.");
    }
    final Class<? extends Attribute> interf = interfaces.getFirst().get();

    // TODO: @deprecated sophisticated(TM) backwards
    if (enableBackwards && toStringMethod.isOverriddenAsOf(clazz)) {
      assert assertExternalClass(clazz) : "no Lucene/Solr classes should fallback to toString() parsing";
      // this class overrides toString and for backwards compatibility we try to parse the string returned by this method:
      for (String part : toString().split(",")) {
        final int pos = part.indexOf('=');
        if (pos < 0) {
          throw new UnsupportedOperationException("The backwards compatibility layer to support reflectWith() " +
            "on old AtributeImpls expects the toString() implementation to return a correct format as specified for method reflectAsString(false)");
        }
        reflector.reflect(interf, part.substring(0, pos).trim(), part.substring(pos + 1));
      }
      return;
    }
    // end sophisticated(TM) backwards

    final Field[] fields = clazz.getDeclaredFields();
    try {
      for (int i = 0; i < fields.length; i++) {
        final Field f = fields[i];
        if (Modifier.isStatic(f.getModifiers())) continue;
        f.setAccessible(true);
        reflector.reflect(interf, f.getName(), f.get(this));
      }
    } catch (IllegalAccessException e) {
      // this should never happen, because we're just accessing fields
      // from 'this'
      throw new RuntimeException(e);
    }
  }
  
  /**
   * Copies the values from this Attribute into the passed-in
   * target attribute. The target implementation must support all the
   * Attributes this implementation supports.
   */
  public abstract void copyTo(AttributeImpl target);
    
  /**
   * Shallow clone. Subclasses must override this if they 
   * need to clone any members deeply,
   */
  @Override
  public Object clone() {
    Object clone = null;
    try {
      clone = super.clone();
    } catch (CloneNotSupportedException e) {
      throw new RuntimeException(e);  // shouldn't happen
    }
    return clone;
  }
}

Other Lucene examples (source code examples)

Here is a short list of links related to this Lucene AttributeImpl.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.