| /* |
| * 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.tamaya.spisupport; |
| |
| import org.apache.tamaya.spi.PropertySource; |
| import org.apache.tamaya.spi.PropertyValue; |
| |
| import java.io.Serializable; |
| import java.util.Comparator; |
| import java.util.logging.Logger; |
| |
| /** |
| * Comparator for ordering of {@link PropertySource}s based on their ordinal method and class name. |
| */ |
| public class PropertySourceComparator implements Comparator<PropertySource>, Serializable { |
| /** serial version UID. */ |
| private static final long serialVersionUID = 1L; |
| |
| private static final Logger LOG = Logger.getLogger(PropertySourceComparator.class.getName()); |
| |
| private static final PropertySourceComparator INSTANCE = new PropertySourceComparator(); |
| |
| private String alternativeOrdinalKey; |
| |
| /** Singleton constructor. */ |
| private PropertySourceComparator(){} |
| |
| /** |
| * Get the shared instance of the comparator. |
| * @return the shared instance, never null. |
| */ |
| public static PropertySourceComparator getInstance(){ |
| return INSTANCE; |
| } |
| |
| |
| /** |
| * Order property source reversely, the most important comes first. |
| * |
| * @param source1 the first PropertySource |
| * @param source2 the second PropertySource |
| * @return the comparison result. |
| */ |
| private int comparePropertySources(PropertySource source1, PropertySource source2) { |
| if (getOrdinal(source1) < getOrdinal(source2)) { |
| return -1; |
| } else if (getOrdinal(source1) > getOrdinal(source2)) { |
| return 1; |
| } else { |
| return source1.getClass().getName().compareTo(source2.getClass().getName()); |
| } |
| } |
| |
| /** |
| * Evaluates an ordinal createValue from a {@link PropertySource}, whereby the ordinal of type {@code int} |
| * is evaluated as follows: |
| * <ol> |
| * <li>It evaluates the {@code String} createValue for {@link PropertySource#TAMAYA_ORDINAL} and tries |
| * to convert it to an {@code int} createValue, using {@link Integer#parseInt(String)}.</li> |
| * <li>It tries to find and evaluate a method {@code int getOrdinal()}.</li> |
| * <li>It tries to find and evaluate a static field {@code int ORDINAL}.</li> |
| * <li>It tries to find and evaluate a class level {@link javax.annotation.Priority} annotation.</li> |
| * <li>It uses the default priority ({@code 0}.</li> |
| * </ol> |
| * @param propertySource the property source, not {@code null}. |
| * @return the ordinal createValue to compare the property source. |
| */ |
| public static int getOrdinal(PropertySource propertySource) { |
| return getOrdinal(propertySource, null); |
| } |
| |
| public static int getOrdinal(PropertySource propertySource, String alternativeOrdinalKey) { |
| if(alternativeOrdinalKey!=null) { |
| PropertyValue ordinalValue = propertySource.get(alternativeOrdinalKey); |
| if (ordinalValue != null) { |
| try { |
| return Integer.parseInt(ordinalValue.getValue().trim()); |
| } catch (Exception e) { |
| LOG.finest("Failed to parse ordinal from " + alternativeOrdinalKey + |
| " in " + propertySource.getName() + ": " + ordinalValue.getValue()); |
| } |
| } |
| } |
| return propertySource.getOrdinal(); |
| } |
| |
| /** |
| * Overrides/adds the key to evaluate/override a property source ordinal. |
| * @param ordinalKey sets the alternative ordinal key, if null default |
| * behaviour will be active. |
| * @return the instance for chaining. |
| */ |
| public PropertySourceComparator setOrdinalKey(String ordinalKey) { |
| this.alternativeOrdinalKey = ordinalKey; |
| return this; |
| } |
| |
| @Override |
| public int compare(PropertySource source1, PropertySource source2) { |
| return comparePropertySources(source1, source2); |
| } |
| |
| } |