001/* 002 Licensed to the Apache Software Foundation (ASF) under one 003 or more contributor license agreements. See the NOTICE file 004 distributed with this work for additional information 005 regarding copyright ownership. The ASF licenses this file 006 to you under the Apache License, Version 2.0 (the 007 "License"); you may not use this file except in compliance 008 with the License. You may obtain a copy of the License at 009 010 http://www.apache.org/licenses/LICENSE-2.0 011 012 Unless required by applicable law or agreed to in writing, 013 software distributed under the License is distributed on an 014 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 KIND, either express or implied. See the License for the 016 specific language governing permissions and limitations 017 under the License. 018 */ 019package org.apache.wiki.util; 020 021import java.util.AbstractList; 022import java.util.concurrent.CopyOnWriteArrayList; 023 024/** 025 * Builds a simple, priority-based List implementation. The list 026 * will be sorted according to the priority. If two items are 027 * inserted with the same priority, their order is the insertion order - i.e. the new one 028 * is appended last in the insertion list. 029 * <p> 030 * Priority is an integer, and the list is sorted in descending order 031 * (that is, 100 is before 10 is before 0 is before -40). 032 */ 033public class PriorityList<E> 034 extends AbstractList<E> 035{ 036 private final CopyOnWriteArrayList<Item<E>> m_elements = new CopyOnWriteArrayList<>(); 037 038 /** 039 * This is the default priority, which is used if no priority 040 * is defined. It's current value is zero. 041 */ 042 public static final int DEFAULT_PRIORITY = 0; 043 044 /** 045 * Adds an object to its correct place in the list, using the 046 * given priority. 047 * 048 * @param o Object to add. 049 * @param priority Priority. 050 */ 051 public void add(final E o, final int priority ) 052 { 053 int i = 0; 054 055 for( ; i < m_elements.size(); i++ ) 056 { 057 final Item< E > item = m_elements.get(i); 058 059 if( item.m_priority < priority ) 060 { 061 break; 062 } 063 } 064 065 final Item<E> newItem = new Item<>(); 066 newItem.m_priority = priority; 067 newItem.m_object = o; 068 069 m_elements.add( i, newItem ); 070 } 071 072 /** 073 * Adds an object using the default priority to the List. 074 * 075 * @param o Object to add. 076 * @return true, as per the general Collections.add contract. 077 */ 078 @Override 079 public boolean add(final E o ) 080 { 081 add( o, DEFAULT_PRIORITY ); 082 083 return true; 084 } 085 086 /** 087 * Returns the object at index "index". 088 * 089 * @param index The index. 090 * @return The object at the list at the position "index". 091 */ 092 @Override 093 public E get(final int index ) 094 { 095 return m_elements.get( index ).m_object; 096 } 097 098 /** 099 * Returns the current size of the list. 100 * 101 * @return size of the list. 102 */ 103 @Override 104 public int size() 105 { 106 return m_elements.size(); 107 } 108 109 /** 110 * Provides a holder for the priority-object 2-tuple. 111 */ 112 private static class Item<E> 113 { 114 public int m_priority; 115 public E m_object; 116 } 117}