001: /*
002: * ProviderOrder.java
003: *
004: * Copyright 2001 Sun Microsystems, Inc. All rights reserved.
005: * PROPRIETARY/CONFIDENTIAL. Use of this product is subject to license terms.
006: */
007:
008: package com.sun.portal.providers.util;
009:
010: import java.util.List;
011: import java.util.TreeMap;
012: import java.util.Map;
013: import java.util.HashMap;
014: import java.util.ArrayList;
015: import java.util.Iterator;
016: import java.util.logging.Logger;
017: import java.util.logging.Level;
018: import java.util.logging.LogRecord;
019:
020: import javax.servlet.http.HttpServletRequest;
021:
022: import com.sun.portal.providers.ProviderWidths;
023: import com.sun.portal.providers.Provider;
024: import com.sun.portal.providers.ProviderException;
025:
026: import com.sun.portal.providers.context.ContainerProviderContext;
027: import com.sun.portal.providers.context.ProviderContextException;
028:
029: import com.sun.portal.desktop.util.Integers;
030: import com.sun.portal.log.common.PortalLogger;
031:
032: /**
033: *
034: */
035:
036: public class ProviderOrder implements ProviderProperties,
037: ProviderWidths {
038:
039: static IntegerStringComparator intStrComp = new IntegerStringComparator();
040: private static Logger logger = PortalLogger
041: .getLogger(ProviderOrder.class);
042:
043: public static List order(
044:
045: List providers, String parent, ContainerProviderContext pc,
046: HttpServletRequest req) throws ProviderException {
047:
048: String ONE = "1";
049: String THREE = "3";
050:
051: Map widths = new HashMap();
052: Map channelsColumn = null;
053: Map channelsRow = null;
054: Map channelsIsMovable = null;
055: boolean dIsMovable = true;
056: String defaultChannelRow = ONE;
057: String defaultChannelColumn = ONE;
058:
059: int layout = 0;
060:
061: try {
062: layout = pc.getIntegerProperty(parent, LAYOUT);
063: channelsColumn = pc.getCollectionProperty(parent,
064: CHANNELS_COLUMN);
065: channelsRow = pc
066: .getCollectionProperty(parent, CHANNELS_ROW);
067: channelsIsMovable = pc.getCollectionProperty(parent,
068: CHANNELS_IS_MOVABLE);
069: defaultChannelRow = pc.getStringProperty(parent,
070: DEFAULT_CHANNEL_ROW);
071: defaultChannelColumn = pc.getStringProperty(parent,
072: DEFAULT_CHANNEL_COLUMN);
073: dIsMovable = pc.getBooleanProperty(parent,
074: DEFAULT_CHANNEL_IS_MOVABLE);
075: } catch (ProviderContextException pce) {
076: throw new ProviderException("ProviderOrder.order(): ", pce);
077: }
078:
079: for (int i = 0; i < providers.size(); i++) {
080: String providerName = (String) providers.get(i);
081: Integer width = null;
082: Provider p = null;
083:
084: try {
085: p = pc.getProvider(req, parent, providerName);
086: if (p == null) {
087: continue;
088: }
089: width = Integers.get(p.getWidth());
090: } catch (ProviderException e) {
091: if (logger.isLoggable(Level.FINE)) {
092: LogRecord record = new LogRecord(Level.FINE,
093: "PSDT_CSPPU0003");
094: record.setLoggerName(logger.getName());
095: record.setParameters(new Object[] { providerName });
096: record.setThrown(e);
097: logger.log(record);
098: }
099: width = Integers.get(ProviderWidths.WIDTH_THICK);
100: }
101:
102: String col = PropertyUtil.getStringValueFromMap(
103: channelsColumn, providerName, defaultChannelColumn);
104: String row = PropertyUtil.getStringValueFromMap(
105: channelsRow, providerName, defaultChannelRow);
106: boolean movable = PropertyUtil.getBooleanValueFromMap(
107: channelsIsMovable, providerName, dIsMovable);
108:
109: if (logger.isLoggable(Level.FINEST)) {
110: LogRecord record = new LogRecord(Level.FINEST,
111: "PSDT_CSPPU0004");
112: record.setLoggerName(logger.getName());
113: record.setParameters(new Object[] { providerName,
114: width, col, row, movable + "" });
115: logger.log(record);
116: }
117:
118: //
119: // fix up the col value so it makes sense according to the width
120: //
121:
122: switch (width.intValue()) {
123: case ProviderWidths.WIDTH_FULL_TOP:
124: case ProviderWidths.WIDTH_FULL_BOTTOM:
125: //
126: // for full widths, col setting doesn't matter, so set it to 1
127: // for everybody
128: //
129: col = ONE;
130: break;
131:
132: case ProviderWidths.WIDTH_THIN:
133: switch (layout) {
134: case Layout.LAYOUT_THIN_THICK:
135: case Layout.LAYOUT_THICK_THIN:
136: //
137: // for these layouts, the col for thin channels doesn't matter
138: // so set it to "1"
139: //
140: col = ONE;
141: break;
142:
143: case Layout.LAYOUT_THIN_THICK_THIN:
144: //
145: // here, only col values of 1 or 2 make sense
146: // for thin, so if its 3 set it to 1
147: //
148: if (col.equals(THREE)) {
149: col = ONE;
150: }
151: break;
152: }
153: break;
154:
155: case ProviderWidths.WIDTH_THICK:
156: //
157: // the col value doesn't matter for thick channels,
158: //set it to 1
159: //
160: col = ONE;
161: break;
162: }
163:
164: //
165: // get the col map from the widths map
166: //
167: Map cols = null;
168: if (!widths.containsKey(width)) {
169: cols = new TreeMap(intStrComp);
170: widths.put(width, cols);
171: } else {
172: cols = (Map) widths.get(width);
173: }
174:
175: //
176: // get the order element from the cols map
177: //
178: ProviderOrder.OrderElement oe = null;
179: if (!cols.containsKey(col)) {
180: oe = new ProviderOrder.OrderElement();
181: cols.put(col, oe);
182: } else {
183: oe = (OrderElement) cols.get(col);
184: }
185: if (logger.isLoggable(Level.FINEST)) {
186: LogRecord record = new LogRecord(Level.FINEST,
187: "PSDT_CSPPU0005");
188: record.setLoggerName(logger.getName());
189: record.setParameters(new Object[] { oe });
190: logger.log(record);
191: }
192: //
193: // get the rows map from the order element
194: //
195: Map rows = null;
196: if (movable) {
197: if (oe.order == null) {
198: oe.order = new TreeMap(intStrComp);
199: }
200: rows = oe.order;
201: } else {
202: if (oe.lockedOrder == null) {
203: oe.lockedOrder = new TreeMap(intStrComp);
204: }
205: rows = oe.lockedOrder;
206: }
207:
208: //
209: // set the channel in the rows map
210: //
211: if (!rows.containsKey(row)) {
212: List newRowList = new ArrayList();
213: newRowList.add(providerName);
214: rows.put(row, newRowList);
215: } else {
216: ((List) rows.get(row)).add(providerName);
217: }
218:
219: //debug.error("ProviderOrder.order(): rows=" + rows);
220:
221: }
222:
223: //
224: // we've built the ordered tree, so flatten it. the following should
225: // be true in the flattend list:
226: //
227: // for all width w and column c, channels in row r precede channels
228: // in row r+1.
229: //
230: // for all width w, column c, and row r, locked channels l precede
231: // non-locked channels u.
232: //
233:
234: List ordered = new ArrayList();
235:
236: for (Iterator l = widths.keySet().iterator(); l.hasNext();) {
237: Integer width = (Integer) l.next();
238: Map cols = (Map) widths.get(width);
239:
240: //
241: // per-width temp list
242: //
243: List widthOrdered = new ArrayList();
244:
245: for (Iterator i = cols.keySet().iterator(); i.hasNext();) {
246: String col = (String) i.next();
247: OrderElement oe = (OrderElement) cols.get(col);
248:
249: //
250: // per-col temp list
251: //
252: List colOrdered = new ArrayList();
253:
254: //
255: // movable are already in order from treemap
256: //
257: if (oe.order != null) {
258: for (Iterator j = oe.order.keySet().iterator(); j
259: .hasNext();) {
260: String index = (String) j.next();
261: colOrdered.addAll((List) oe.order.get(index));
262: }
263: }
264:
265: //
266: // now insert non-movable
267: //
268: if (oe.lockedOrder != null) {
269: for (Iterator j = oe.lockedOrder.keySet()
270: .iterator(); j.hasNext();) {
271: String index = (String) j.next();
272:
273: //
274: // make sure index is positive, and index is not
275: // off the end of the list
276: int k = Math.max(Math
277: .min(Integer.parseInt(index) - 1,
278: colOrdered.size()), 0);
279: colOrdered.addAll(k, (List) oe.lockedOrder
280: .get(index));
281: }
282: }
283:
284: widthOrdered.addAll(colOrdered);
285: }
286: ordered.addAll(widthOrdered);
287: }
288:
289: return ordered;
290: }
291:
292: private static class OrderElement {
293: public Map order = null;
294: public Map lockedOrder = null;
295: }
296: }
|