001: /**
002: * $Id: ChannelOrder.java,v 1.8 2005/09/21 10:49:00 dg154973 Exp $
003: * Copyright 2002 Sun Microsystems, Inc. All
004: * rights reserved. Use of this product is subject
005: * to license terms. Federal Acquisitions:
006: * Commercial Software -- Government Users
007: * Subject to Standard License Terms and
008: * Conditions.
009: *
010: * Sun, Sun Microsystems, the Sun logo, and Sun ONE
011: * are trademarks or registered trademarks of Sun Microsystems,
012: * Inc. in the United States and other countries.
013: */package com.sun.portal.wireless.providers.containers.util;
014:
015: import java.util.ArrayList;
016: import java.util.List;
017: import java.util.Map;
018: import java.util.Set;
019: import java.util.TreeMap;
020: import java.util.Iterator;
021: import java.util.Comparator;
022: import java.util.logging.Level;
023: import java.util.logging.Logger;
024: import java.lang.Integer;
025: import java.lang.Boolean;
026:
027: import com.sun.portal.log.common.PortalLogger;
028: import com.sun.portal.providers.context.ContainerProviderContext;
029: import com.sun.portal.providers.context.ProviderContextException;
030: import com.sun.portal.providers.ProviderException;
031:
032: public class ChannelOrder {
033:
034: public final static String CHANNELSROW = "channelsRow";
035: public final static String DEFAULTCHANNELROW = "defaultChannelRow";
036: public final static String DEFAULTCHANNELISMOVABLE = "defaultChannelIsMovable";
037: public final static String CHANNELSISMOVABLE = "channelsIsMovable";
038:
039: private static Logger sLogger = PortalLogger
040: .getLogger(ChannelOrder.class);
041:
042: /*
043: *
044: * This method basically implements the algorithm to order a list of providers
045: * according to factors like CHANNELSROW and CHANNELSISMOVABLE.
046: *
047: */
048: public static List order(List channels, String container,
049: ContainerProviderContext context, boolean onlyMovable)
050: throws ProviderException {
051:
052: Map channelsRow = null;
053: Map channelsIsMovable = null;
054: String defaultChannelRow = null;
055: boolean defaultChannelIsMovable = false;
056: try {
057: channelsRow = context.getCollectionProperty(container,
058: CHANNELSROW);
059: channelsIsMovable = context.getCollectionProperty(
060: container, CHANNELSISMOVABLE);
061: defaultChannelRow = context.getStringProperty(container,
062: DEFAULTCHANNELROW);
063: defaultChannelIsMovable = context.getBooleanProperty(
064: container, DEFAULTCHANNELISMOVABLE);
065: } catch (ProviderContextException e) {
066: throw new ProviderException("ChannelOrder.order(): ", e);
067: }
068: ChannelElementComparator comparator = new ChannelElementComparator();
069:
070: TreeMap orderedMap = new TreeMap(comparator);
071: TreeMap nonMovableMap = new TreeMap(comparator);
072: String name, row;
073: boolean isMovable;
074:
075: // Go thru each channel and sort them according to their row value.
076: // If the channel doesn't have a row value, the default is used.
077: // We will first sort only the movable channels, storing the non-movable
078: // and re-insert them according to their respective order
079: for (int i = 0; i < channels.size(); i++) {
080:
081: // Get channel name
082: name = (String) channels.get(i);
083:
084: // Get the row of the channel
085: if (channelsRow.containsKey(name)) {
086: row = (String) channelsRow.get(name);
087: } else {
088: row = defaultChannelRow;
089: }
090:
091: // get isMovable for channel
092: if (channelsIsMovable.containsKey(name)) {
093: isMovable = ((Boolean) channelsIsMovable.get(name))
094: .booleanValue();
095: } else {
096: isMovable = defaultChannelIsMovable;
097: }
098:
099: // Create the ordered channel element
100: ChannelElement element = new ChannelElement(Integer
101: .parseInt(row), i);
102:
103: if (isMovable) {
104: orderedMap.put(element, name);
105: } else {
106: nonMovableMap.put(element, name);
107: }
108: }
109:
110: // Now tht we have the channels sorted according to their row,
111: // flatten it back to a list
112:
113: List orderedList = null;
114: if (orderedMap.size() > 0) {
115:
116: orderedList = new ArrayList(orderedMap.values());
117: sLogger.log(Level.FINEST, "PSMA_CSPWPCU00002");
118:
119: } else {
120: sLogger.log(Level.FINEST, "PSMA_CSPWPCU00003");
121: orderedList = new ArrayList();
122: }
123:
124: // only return movable channels
125: if (onlyMovable) {
126:
127: return orderedList;
128:
129: } else { // include non-movable channels
130:
131: // Re-insert the non-movable channels according to their locked order
132: Set nonMovableEntries = nonMovableMap.entrySet();
133: Iterator iterator = nonMovableEntries.iterator();
134:
135: while (iterator.hasNext()) {
136: // Get the map entry
137: Map.Entry entry = (Map.Entry) iterator.next();
138: ChannelElement key = (ChannelElement) entry.getKey();
139: String value = (String) entry.getValue();
140: int idx = key.row;
141:
142: sLogger.log(Level.FINEST, "PSMA_CSPWPCU00004", String
143: .valueOf(idx));
144:
145: // Make sure we don't exceed the array boundary
146: // Don't forget tht list index is zero-based
147:
148: if (idx <= orderedList.size()) {
149:
150: // Size ok, insert
151: //context.debugMessage("IDX is < orderedList SIZE");
152:
153: orderedList.add(idx - 1, value);
154:
155: } else {
156:
157: // We are bigger than the number of channels, add to end
158: sLogger.finest("PSMA_CSPWPCU00005");
159: orderedList.add(orderedList.size(), value);
160: }
161: }
162:
163: return orderedList;
164: }
165: }
166:
167: /*
168: * Inner class for comparator elements
169: *
170: */
171: public static class ChannelElement {
172:
173: public int row;
174: public int index;
175:
176: public ChannelElement(int row, int index) {
177: this .row = row;
178: this .index = index;
179: }
180: }
181:
182: /*
183: * Inner class for comparator.
184: *
185: * This class compares OrderElement first using the row index and
186: * followed by their hash code (We dont really care, abt the order
187: * but we do want to have multiple entries with same row index.
188: *
189: */
190: public static class ChannelElementComparator implements Comparator {
191:
192: public int compare(Object o1, Object o2) {
193:
194: ChannelElement channel1 = (ChannelElement) o1;
195: ChannelElement channel2 = (ChannelElement) o2;
196:
197: if (channel1.row == channel2.row) {
198: // Use their existing order in the channel list
199: return (channel1.index - channel2.index);
200: } else {
201: // Use their row index
202: return (channel1.row - channel2.row);
203: }
204: }
205: }
206: }
|