Solr.AttributeFactory源码分析

2021SC@SDUSC

/*
 * 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.
 */
package org.apache.lucene.util;


import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.UndeclaredThrowableException;

/**
  * AttributeFactory 创建 {@link AttributeImpl} 的实例。
 */
public abstract class AttributeFactory {
  
 /**
    * 为提供的 {@link Attribute} 接口类返回一个 {@link AttributeImpl}。
    *
    * @throws UndeclaredThrowableException 一个包装运行时异常抛出,如果
    * 属性类的构造函数抛出一个检查异常。
    * 请注意,属性不应抛出或声明
    * 检查异常; 这可能会在未来早期得到验证并失败。
    */
  public abstract AttributeImpl createAttributeInstance(Class<? extends Attribute> attClass)
      throws UndeclaredThrowableException;
  
/**
    * 为给定类的无参数构造函数返回正确类型的 {@link MethodHandle}。
    */
  static final MethodHandle findAttributeImplCtor(Class<? extends AttributeImpl> clazz) {
    try {
      return lookup.findConstructor(clazz, NO_ARG_CTOR).asType(NO_ARG_RETURNING_ATTRIBUTEIMPL);
    } catch (NoSuchMethodException | IllegalAccessException e) {
      throw new IllegalArgumentException("Cannot lookup accessible no-arg constructor for: " + clazz.getName(), e);
    }
  }
  
  private static final MethodHandles.Lookup lookup = MethodHandles.publicLookup();
  private static final MethodType NO_ARG_CTOR = MethodType.methodType(void.class);
  private static final MethodType NO_ARG_RETURNING_ATTRIBUTEIMPL = MethodType.methodType(AttributeImpl.class);
  
 /**
    * 这是使用 {@link AttributeImpl} 创建的
    * 提供的 {@link Attribute} 接口类的类名,通过附加 <code>Impl</code> 到它。
    */
  public static final AttributeFactory DEFAULT_ATTRIBUTE_FACTORY = new DefaultAttributeFactory();
  
  private static final class DefaultAttributeFactory extends AttributeFactory {
    private final ClassValue<MethodHandle> constructors = new ClassValue<MethodHandle>() {
      @Override
      protected MethodHandle computeValue(Class<?> attClass) {
        return findAttributeImplCtor(findImplClass(attClass.asSubclass(Attribute.class)));
      }
    };

    DefaultAttributeFactory() {}

    @Override
    public AttributeImpl createAttributeInstance(Class<? extends Attribute> attClass) {
      try {
        return (AttributeImpl) constructors.get(attClass).invokeExact();
      } catch (Error | RuntimeException e) {
        throw e;
      } catch (Throwable e) {
        throw new UndeclaredThrowableException(e);
      }
    }

    private Class<? extends AttributeImpl> findImplClass(Class<? extends Attribute> attClass) {
      try {
        return Class.forName(attClass.getName() + "Impl", true, attClass.getClassLoader()).asSubclass(AttributeImpl.class);
      } catch (ClassNotFoundException cnfe) {
        throw new IllegalArgumentException("Cannot find implementing class for: " + attClass.getName());
      }      
    }
  }
  
/** <b>Expert</b>: AttributeFactory 返回给定 {@code clazz} 的实例,用于
    * 它实现的属性。 对于所有其他属性,它调用给定的委托工厂
    * 作为后备。 此类可用于首选特定的 {@code AttributeImpl}
    * 在不同的类上组合多个属性。
    * @lucene.internal
    */
  public abstract static class StaticImplementationAttributeFactory<A extends AttributeImpl> extends AttributeFactory {
    private final AttributeFactory delegate;
    private final Class<A> clazz;
    
    /** <b>Expert</b>:创建一个返回 {@code clazz} 作为实例的 AttributeFactory
      * 它实现的属性和所有其他属性调用给定的委托工厂。 */
    public StaticImplementationAttributeFactory(AttributeFactory delegate, Class<A> clazz) {
      this.delegate = delegate;
      this.clazz = clazz;
    }
    
    @Override
    public final AttributeImpl createAttributeInstance(Class<? extends Attribute> attClass) {
      return attClass.isAssignableFrom(clazz) ? createInstance() : delegate.createAttributeInstance(attClass);
    }
    
    /** Creates an instance of {@code A}. */
    protected abstract A createInstance();
    
    @Override
    public boolean equals(Object other) {
      if (this == other)
        return true;
      if (other == null || other.getClass() != this.getClass())
        return false;
      @SuppressWarnings("rawtypes")
      final StaticImplementationAttributeFactory af = (StaticImplementationAttributeFactory) other;
      return this.delegate.equals(af.delegate) && this.clazz == af.clazz;
    }
    
    @Override
    public int hashCode() {
      return 31 * delegate.hashCode() + clazz.hashCode();
    }
  }
  
 /** 返回一个 AttributeFactory 返回给定 {@code clazz} 的实例
    * 它实现的属性。 给定的 {@code clazz} 必须有一个公共的无参数构造函数。
    * 对于所有其他属性,它调用给定的委托工厂作为回退。
    * 此方法可用于偏好特定的 {@code AttributeImpl},它结合了
    * 不同类的多个属性。
    * <p>请将此方法创建的实例保存在静态final字段中,因为
    * 在每次调用时,这都会反射以创建 {@link MethodHandle}。
    */
  public static <A extends AttributeImpl> AttributeFactory getStaticImplementation(AttributeFactory delegate, Class<A> clazz) {
    final MethodHandle constr = findAttributeImplCtor(clazz);
    return new StaticImplementationAttributeFactory<A>(delegate, clazz) {
      @Override
      protected A createInstance() {
        try {
          return (A) constr.invokeExact();
        } catch (Error | RuntimeException e) {
          throw e;
        } catch (Throwable e) {
          throw new UndeclaredThrowableException(e);
        }
      }
    };
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值