/** @author <a href="mailto:[email protected]">Lincoln Baxter, III</a> */
public class BundleTemplateMessageImpl implements BundleTemplateMessage {
  @Inject TemplateMessage template;

  private String textDefault;
  private BundleKey textKey;

  @Inject ApplicationBundles bundles;

  @Inject @Client Locale clientLocale;

  private final Logger log = Logger.getLogger(BundleTemplateMessageImpl.class);

  public Message build() {
    String text;
    try {
      text = bundles.get(clientLocale, textKey.getBundle()).getString(textKey.getKey());
    } catch (Exception e) {
      log.warn("Could not load bundle: " + textKey);
      text = textDefault;
    }

    if ((text == null) || "".equals(text)) {
      text = textKey.toString();
    }

    template.text(text);
    return template.build();
  }

  /*
   * Setters
   */

  public BundleTemplateMessageImpl key(final BundleKey text) {
    this.textKey = text;
    return this;
  }

  public BundleTemplateMessage defaults(final String text) {
    this.textDefault = text;
    return this;
  }

  public BundleTemplateMessageImpl params(final Object... textParams) {
    this.template.textParams(textParams);
    return this;
  }

  public BundleTemplateMessage targets(final String targets) {
    this.template.targets(targets);
    return this;
  }

  public BundleTemplateMessage level(final Level level) {
    this.template.level(level);
    return this;
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((template == null) ? 0 : template.hashCode());
    result = prime * result + ((textDefault == null) ? 0 : textDefault.hashCode());
    result = prime * result + ((textKey == null) ? 0 : textKey.hashCode());
    return result;
  }

  @Override
  public boolean equals(final Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (getClass() != obj.getClass()) {
      return false;
    }
    BundleTemplateMessageImpl other = (BundleTemplateMessageImpl) obj;
    if (template == null) {
      if (other.template != null) {
        return false;
      }
    } else if (!template.equals(other.template)) {
      return false;
    }
    if (textDefault == null) {
      if (other.textDefault != null) {
        return false;
      }
    } else if (!textDefault.equals(other.textDefault)) {
      return false;
    }
    if (textKey == null) {
      if (other.textKey != null) {
        return false;
      }
    } else if (!textKey.equals(other.textKey)) {
      return false;
    }
    return true;
  }
}
示例#2
0
/**
 * Data store for view specific data.
 *
 * @author Stuart Douglas
 * @author <a href="mailto:[email protected]">Brian Leathem</a>
 */
@ApplicationScoped
public class ViewConfigStoreImpl implements ViewConfigStore {
  private final transient Logger log = Logger.getLogger(SecurityPhaseListener.class);
  /** cache of viewId to a given data list */
  private final ConcurrentHashMap<
          Class<? extends Annotation>, ConcurrentHashMap<String, List<? extends Annotation>>>
      annotationCache =
          new ConcurrentHashMap<
              Class<? extends Annotation>, ConcurrentHashMap<String, List<? extends Annotation>>>();

  private final ConcurrentHashMap<
          Class<? extends Annotation>, ConcurrentHashMap<String, List<? extends Annotation>>>
      qualifierCache =
          new ConcurrentHashMap<
              Class<? extends Annotation>, ConcurrentHashMap<String, List<? extends Annotation>>>();

  private final ConcurrentHashMap<
          Class<? extends Annotation>, ConcurrentHashMap<String, Annotation>>
      viewPatternDataByAnnotation =
          new ConcurrentHashMap<
              Class<? extends Annotation>, ConcurrentHashMap<String, Annotation>>();
  private final ConcurrentHashMap<
          Class<? extends Annotation>, ConcurrentHashMap<String, List<? extends Annotation>>>
      viewPatternDataByQualifier =
          new ConcurrentHashMap<
              Class<? extends Annotation>, ConcurrentHashMap<String, List<? extends Annotation>>>();

  /**
   * setup the bean with the configuration from the extension
   *
   * <p>It would be better if the extension could do this, but the extension cannot resolve the bean
   * until after all lifecycle events have been processed
   */
  @Inject
  public void setup(ViewConfigExtension extension) {
    for (Entry<String, Set<Annotation>> e : extension.getData().entrySet()) {
      for (Annotation i : e.getValue()) {
        addAnnotationData(e.getKey(), i);
      }
    }
  }

  @Override
  public synchronized void addAnnotationData(String viewId, Annotation annotation) {
    ConcurrentHashMap<String, Annotation> annotationMap =
        viewPatternDataByAnnotation.get(annotation.annotationType());
    if (annotationMap == null) {
      annotationMap = new ConcurrentHashMap<String, Annotation>();
      viewPatternDataByAnnotation.put(annotation.annotationType(), annotationMap);
      log.debugf(
          "Putting new annotation map for anotation type %s",
          annotation.annotationType().getName());
    }
    annotationMap.put(viewId, annotation);
    log.debugf(
        "Putting new annotation (type: %s) for viewId: %s",
        annotation.annotationType().getName(), viewId);

    Annotation[] annotations = annotation.annotationType().getAnnotations();
    for (Annotation qualifier : annotations) {
      if (qualifier.annotationType().getName().startsWith("java.")) {
        log.debugf("Disregarding java.* package %s", qualifier.annotationType().getName());
        continue;
      }
      ConcurrentHashMap<String, List<? extends Annotation>> qualifierMap =
          viewPatternDataByQualifier.get(qualifier.annotationType());
      if (qualifierMap == null) {
        qualifierMap = new ConcurrentHashMap<String, List<? extends Annotation>>();
        viewPatternDataByQualifier.put(qualifier.annotationType(), qualifierMap);
        log.debugf(
            "Putting new qualifier map for qualifier type %s",
            qualifier.annotationType().getName());
      }
      List<Annotation> qualifiedAnnotations = new ArrayList<Annotation>();
      List<? extends Annotation> exisitngQualifiedAnnotations = qualifierMap.get(viewId);
      if (exisitngQualifiedAnnotations != null && !exisitngQualifiedAnnotations.isEmpty()) {
        qualifiedAnnotations.addAll(exisitngQualifiedAnnotations);
      }
      qualifiedAnnotations.add(annotation);
      log.debugf(
          "Adding new annotation (type: %s) for viewId: %s and Qualifier %s",
          annotation.annotationType().getName(), viewId, qualifier.annotationType().getName());
      qualifierMap.put(viewId, qualifiedAnnotations);
    }
  }

  @Override
  public <T extends Annotation> T getAnnotationData(String viewId, Class<T> type) {
    List<T> data =
        prepareAnnotationCache(viewId, type, annotationCache, viewPatternDataByAnnotation);
    if ((data != null) && (data.size() > 0)) {
      return data.get(0);
    }
    return null;
  }

  @Override
  public <T extends Annotation> List<T> getAllAnnotationData(String viewId, Class<T> type) {
    List<T> data =
        prepareAnnotationCache(viewId, type, annotationCache, viewPatternDataByAnnotation);
    if (data != null) {
      return Collections.unmodifiableList(data);
    }
    return null;
  }

  @Override
  public <T extends Annotation> Map<String, Annotation> getAllAnnotationViewMap(Class<T> type) {
    return viewPatternDataByAnnotation.get(type);
  }

  @Override
  public List<? extends Annotation> getAllQualifierData(
      String viewId, Class<? extends Annotation> qualifier) {
    List<? extends Annotation> data =
        prepareQualifierCache(viewId, qualifier, qualifierCache, viewPatternDataByQualifier);
    if (data != null) {
      return Collections.unmodifiableList(data);
    }
    return null;
  }

  private <T extends Annotation> List<T> prepareAnnotationCache(
      String viewId,
      Class<T> annotationType,
      ConcurrentHashMap<
              Class<? extends Annotation>, ConcurrentHashMap<String, List<? extends Annotation>>>
          cache,
      ConcurrentHashMap<Class<? extends Annotation>, ConcurrentHashMap<String, Annotation>>
          viewPatternData) {
    // we need to synchronize to make sure that no threads see a half
    // completed list due to instruction re-ordering
    ConcurrentHashMap<String, List<? extends Annotation>> map = cache.get(annotationType);
    if (map == null) {
      ConcurrentHashMap<String, List<? extends Annotation>> newMap =
          new ConcurrentHashMap<String, List<? extends Annotation>>();
      map = cache.putIfAbsent(annotationType, newMap);
      if (map == null) {
        map = newMap;
      }
    }
    List<? extends Annotation> annotationData = map.get(viewId);
    if (annotationData == null) {
      List<Annotation> newList = new ArrayList<Annotation>();
      Map<String, Annotation> viewPatterns = viewPatternData.get(annotationType);
      if (viewPatterns != null) {
        List<String> resultingViews = findViewsWithPatternsThatMatch(viewId, viewPatterns.keySet());
        for (String i : resultingViews) {
          newList.add(viewPatterns.get(i));
        }
      }

      annotationData = map.putIfAbsent(viewId, newList);
      if (annotationData == null) {
        annotationData = newList;
      }
    }
    return (List) annotationData;
  }

  private <T extends Annotation> List<T> prepareQualifierCache(
      String viewId,
      Class<T> qualifierType,
      ConcurrentHashMap<
              Class<? extends Annotation>, ConcurrentHashMap<String, List<? extends Annotation>>>
          cache,
      ConcurrentHashMap<
              Class<? extends Annotation>, ConcurrentHashMap<String, List<? extends Annotation>>>
          viewPatternData) {
    // we need to synchronize to make sure that no threads see a half
    // completed list due to instruction re-ordering
    ConcurrentHashMap<String, List<? extends Annotation>> map = cache.get(qualifierType);
    if (map == null) {
      ConcurrentHashMap<String, List<? extends Annotation>> newMap =
          new ConcurrentHashMap<String, List<? extends Annotation>>();
      map = cache.putIfAbsent(qualifierType, newMap);
      if (map == null) {
        map = newMap;
      }
    }
    List<? extends Annotation> annotationData = map.get(viewId);
    if (annotationData == null) {
      List<Annotation> newList = new ArrayList<Annotation>();
      Map<String, List<? extends Annotation>> viewPatterns = viewPatternData.get(qualifierType);
      if (viewPatterns != null) {
        List<String> resultingViews = findViewsWithPatternsThatMatch(viewId, viewPatterns.keySet());
        for (String i : resultingViews) {
          newList.addAll(viewPatterns.get(i));
        }
      }
      Collections.sort(newList, new AnnotationNameComparator());
      annotationData = map.putIfAbsent(viewId, newList);
      if (annotationData == null) {
        annotationData = newList;
      }
    }
    return (List) annotationData;
  }

  private List<String> findViewsWithPatternsThatMatch(String viewId, Set<String> viewPatterns) {
    List<String> resultingViews = new ArrayList<String>();
    for (String viewPattern : viewPatterns) {
      if (viewPattern.endsWith("*")) {
        String cutView = viewPattern.substring(0, viewPattern.length() - 1);
        if (viewId.startsWith(cutView)) {
          resultingViews.add(viewPattern);
        }
      } else {
        if (viewPattern.equals(viewId)) {
          resultingViews.add(viewPattern);
        }
      }
    }
    // sort the keys by length, longest is the most specific and so should go first
    Collections.sort(resultingViews, StringLengthComparator.INSTANCE);
    return resultingViews;
  }

  private static class StringLengthComparator implements Comparator<String> {

    @Override
    public int compare(String o1, String o2) {
      if (o1.length() > o2.length()) {
        return -1;
      }
      if (o1.length() < o2.length()) {
        return 1;
      }
      return 0;
    }

    public static final StringLengthComparator INSTANCE = new StringLengthComparator();
  }

  private static class AnnotationNameComparator implements Comparator<Annotation> {

    @Override
    public int compare(Annotation o1, Annotation o2) {
      return o1.annotationType().getName().compareTo(o2.annotationType().getName());
    }

    public static final StringLengthComparator INSTANCE = new StringLengthComparator();
  }
}