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 */
019 package org.apache.wiki.util;
020
021 import java.util.AbstractList;
022 import 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 */
033 public class PriorityList<E>
034 extends AbstractList<E>
035 {
036 private CopyOnWriteArrayList<Item<E>> m_elements = new CopyOnWriteArrayList<Item<E>>();
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( E o, int priority )
052 {
053 int i = 0;
054
055 for( ; i < m_elements.size(); i++ )
056 {
057 Item item = m_elements.get(i);
058
059 if( item.m_priority < priority )
060 {
061 break;
062 }
063 }
064
065 Item<E> newItem = new Item<E>();
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 public boolean add( E o )
079 {
080 add( o, DEFAULT_PRIORITY );
081
082 return true;
083 }
084
085 /**
086 * Returns the object at index "index".
087 *
088 * @param index The index.
089 * @return The object at the list at the position "index".
090 */
091 public E get( int index )
092 {
093 return m_elements.get( index ).m_object;
094 }
095
096 /**
097 * Returns the current size of the list.
098 *
099 * @return size of the list.
100 */
101 public int size()
102 {
103 return m_elements.size();
104 }
105
106 /**
107 * Provides a holder for the priority-object 2-tuple.
108 */
109 private static class Item<E>
110 {
111 public int m_priority;
112 public E m_object;
113 }
114 }