001: /**********************************************************************************
002:
003: Feedzeo!
004: A free and open source RSS/Atom/RDF feed aggregator
005:
006: Copyright (C) 2005-2006 Anand Rao (anandrao@users.sourceforge.net)
007:
008: This library is free software; you can redistribute it and/or
009: modify it under the terms of the GNU Lesser General Public
010: License as published by the Free Software Foundation; either
011: version 2.1 of the License, or (at your option) any later version.
012:
013: This library is distributed in the hope that it will be useful,
014: but WITHOUT ANY WARRANTY; without even the implied warranty of
015: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: Lesser General Public License for more details.
017:
018: You should have received a copy of the GNU Lesser General Public
019: License along with this library; if not, write to the Free Software
020: Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
021:
022: ************************************************************************************/package layout;
023:
024: import java.util.*;
025:
026: import util.*;
027:
028: /**
029: *
030: * @author Anand Rao
031: */
032: public class LayoutManager {
033:
034: private final int DEFAULT_TABLE_ROWS = 15;
035: private final int DEFAULT_TABLE_COLS = 2;
036: private final String PAGE_PROPERTY_MAIN = "mainpage";
037: private final String PAGE_PROPERTY_TABLE = "table";
038: private final String TABLE_PROPERTY_TYPE = "type";
039: private final String TABLE_PROPERTY_ROWS = "rows";
040: private final String TABLE_PROPERTY_COLS = "cols";
041: private final String CELL_PROPERTY_LINK = "link";
042:
043: private Vector TableLayoutList; // list holding TableLayout objects
044: private Vector PageLayoutList; // list holding PageLayout objects
045:
046: private TableLayout findTable(String tablename) {
047: for (int i = 0; i < TableLayoutList.size(); i++) {
048: String tbllayout = ((TableLayout) TableLayoutList
049: .elementAt(i)).getName();
050: if (tablename.equalsIgnoreCase(tbllayout))
051: return (TableLayout) TableLayoutList.elementAt(i);
052: }
053: return null;
054: }
055:
056: private int parseRow(String tmp) {
057: StringBuffer row = new StringBuffer();
058: for (int i = 0; i < tmp.length(); i++) {
059: char c = tmp.charAt(i);
060: if (c == ' ')
061: continue;
062: if (c == '(')
063: continue;
064: if (c == ',')
065: break;
066: if (c == ')')
067: break;
068: row.append(c);
069: }
070: return Integer.parseInt(row.toString());
071: }
072:
073: private int parseCol(String tmp) {
074: StringBuffer col = new StringBuffer();
075: int i = 0;
076: while (i < tmp.length()) {
077: if (tmp.charAt(i) == ',') {
078: i++; // i now points to char next to ','
079: break;
080: }
081: i++;
082: }
083:
084: for (int j = i; j < tmp.length(); j++) {
085: char c = tmp.charAt(j);
086: if (c == ' ')
087: continue;
088: if (c == ')')
089: break;
090: col.append(c);
091: }
092: return Integer.parseInt(col.toString());
093: }
094:
095: /*
096: * parses a table specification into a tablelayout object
097: * Table spec:
098: * <table name>
099: * {
100: * type=table;
101: * rows=<number> | -1; //-1 if rows is not known beforehand
102: * cols=<number> | -1;
103: * (0,0)=<dataobjname> | <table name> ; //cell0,0 Note: table name
104: * should be already parsed
105: * (0,1)=<dataobjname>; link=<page name>; // here cell contains a
106: * link to a page which has
107: * layout defined by pagename
108: * (-1,0) | (0,-1)=<dataobjname>; link=<page name>;
109: * // when the user doesn't know the no of
110: * // rows or cols he needs to specify the
111: * // datatype for just one cell; All cells
112: * // in the table are of the same type
113: *
114: * }
115: */
116: private TableLayout buildTable(LayoutInputFileParser lp,
117: String Tblname) {
118: TableLayout TLayout = null;
119: int NumRows = 1, NumCols = 1;
120: boolean IsTableList = false; // set to true if we find that the user doesn't
121: // how many rows or cols need to be created for
122: // this table; This can happen when the no of rows
123: // or cols depends on the no of data items which
124: // can change from case to case basis
125:
126: int Lastcellrow = 0, Lastcellcol = 0; // tracks the row,col of last cell created
127: String line;
128:
129: lp.initTableCursor(Tblname);
130: //System.out.println("BUILD TABLE "+Tblname);
131:
132: while ((line = lp.getNextTableElement(Tblname)) != null) {
133: MultiPropertyList mpl = new MultiPropertyList(';', line);
134: int i = 0;
135: String prop;
136:
137: while ((prop = mpl.getProperty(i)) != null) {
138: //System.out.println("Tablebuilder: parse: "+prop);
139: i++;
140: NameValueListPair nvp = new NameValueListPair(prop);
141: String name, value;
142: name = nvp.getName();
143:
144: if (name.equalsIgnoreCase(TABLE_PROPERTY_TYPE))
145: continue; //nothing to do
146:
147: else if (name.equalsIgnoreCase(TABLE_PROPERTY_ROWS)) {
148: NumRows = Integer.parseInt(nvp.getValueList());
149: //System.out.println("Table "+Tblname+" Rows:"+NumRows);
150: if (NumRows < 0) {
151: IsTableList = true; //we don't know how many rows to create
152: NumRows = DEFAULT_TABLE_ROWS; // set to a default value
153: }
154: //System.out.println("Table "+Tblname+" Rows:"+NumRows);
155: }
156:
157: else if (name.equalsIgnoreCase(TABLE_PROPERTY_COLS)) {
158: NumCols = Integer.parseInt(nvp.getValueList());
159: //System.out.println("Table "+Tblname+" Cols:"+NumCols);
160: if (NumCols < 0) {
161: IsTableList = true;
162: NumCols = DEFAULT_TABLE_COLS;
163: }
164: //System.out.println("Table "+Tblname+" Cols:"+NumCols);
165: TLayout = new TableLayout(Tblname, NumRows, NumCols);
166: if (IsTableList)
167: TLayout.setTableListType(true);
168: }
169:
170: else if (name.equalsIgnoreCase(CELL_PROPERTY_LINK)) {
171: String pagename = nvp.getValueList();
172: if (!IsTableList) { // this is a normal table with finite rows & cols
173: CellElement cell = TLayout.getCell(Lastcellrow,
174: Lastcellcol);
175: cell.setLinkPageLayout(pagename);
176: } else {
177: for (int m = 0; m < NumRows; m++) {
178: for (int n = 0; n < NumCols; n++) {
179: CellElement cell = TLayout
180: .getCell(m, n);
181: cell.setLinkPageLayout(pagename);
182: }
183: }
184: }
185: }
186:
187: else { // we are in a cell definition, by this time tablelayout
188: // object must have been created
189: if (TLayout == null) {
190: ExceptionUtil
191: .reportException(new Exception(
192: "LayoutManager:found cell definition before table defined"));
193: return null;
194: }
195:
196: String cellRC = nvp.getName();
197: String celltype = nvp.getValueList();
198: Lastcellrow = parseRow(cellRC);
199: Lastcellcol = parseCol(cellRC);
200: TableLayout tblcell = findTable(celltype);
201:
202: if (!IsTableList) { // this is a normal table with finite rows & cols
203: TLayout.addCell(Lastcellrow, Lastcellcol,
204: celltype, null, null);
205: if (tblcell != null) {
206: // user defined a cell containing a table; add the table
207: // which has been previously defined to this cell
208: //System.out.println("SIMPLE TABLE "+Tblname+" has cell as tbl "+celltype);
209: CellElement cell = TLayout.getCell(
210: Lastcellrow, Lastcellcol);
211: cell.addTable(tblcell);
212: }
213: } else {
214:
215: // if we are dealing with unknown rows or cols
216: // the user specifies only 1 cell definition;
217: // hence we need to create all the cells at one go
218: // with the same cell type
219:
220: for (int m = 0; m < NumRows; m++) {
221: for (int n = 0; n < NumCols; n++) {
222: TLayout.addCell(m, n, celltype, "",
223: null);
224: if (tblcell != null) {
225: // we have a list of cells where each cell
226: // contains a table; we need to create a
227: // tablelayout object for each cell and add it to the cell
228: //System.out.println("LIST TABLE "+Tblname+" has cell as tbl "+celltype);
229: TableLayout t = new TableLayout(
230: tblcell);
231: TLayout.getCell(m, n).addTable(t);
232: }
233: }
234: }
235: }
236: }
237: }
238: }
239: return TLayout;
240: }
241:
242: /*
243: * Parse the pagelayout format
244: * eg:
245: * <page name>
246: * {
247: * table=<tbl name>;
248: * mainpage=true; // this property is optional
249: * }
250: *
251: */
252:
253: private PageLayout buildPage(LayoutInputFileParser lp,
254: String Pagename) {
255: String line;
256: lp.initPageCursor(Pagename);
257: PageLayout page = new PageLayout(Pagename);
258:
259: while ((line = lp.getNextPageElement(Pagename)) != null) {
260: MultiPropertyList mpl = new MultiPropertyList(';', line);
261: int i = 0;
262: String prop;
263:
264: while ((prop = mpl.getProperty(i)) != null) {
265: i++;
266: NameValueListPair nvp = new NameValueListPair(prop);
267: String name, value;
268: name = nvp.getName();
269:
270: if (name.equalsIgnoreCase(PAGE_PROPERTY_TABLE)) {
271: TableLayout tblmain = findTable(nvp.getValueList());
272: if (tblmain == null) {
273: ExceptionUtil
274: .reportException(new Exception(
275: "Table must be defined before including in a page"));
276: return null;
277: }
278: page.setMainTable(tblmain);
279: } else if (name.equalsIgnoreCase(PAGE_PROPERTY_MAIN)) {
280: if (nvp.getValueList().equalsIgnoreCase("true"))
281: page.setStartPage(true);
282: else
283: page.setStartPage(false);
284: }
285: }
286: }
287: return page;
288: }
289:
290: /** Creates a new instance of LayoutManager */
291: public LayoutManager() {
292: TableLayoutList = new Vector();
293: PageLayoutList = new Vector();
294: }
295:
296: public void createFramework(String filename) {
297: LayoutInputFileParser lparser;
298: try {
299: lparser = new LayoutInputFileParser(filename);
300: } catch (Exception e) {
301: ExceptionUtil.reportException(e);
302: return;
303: }
304: // build table objects
305: for (int i = 0; i < lparser.getNumTables(); i++) {
306: String Tblname = lparser.getTable(i);
307: TableLayout tbl = buildTable(lparser, Tblname);
308: if (tbl != null)
309: TableLayoutList.addElement(tbl);
310: }
311:
312: // build page objects
313: for (int i = 0; i < lparser.getNumPages(); i++) {
314: String Pagename = lparser.getPage(i);
315: PageLayout page = buildPage(lparser, Pagename);
316: if (page != null)
317: PageLayoutList.addElement(page);
318: }
319: lparser.closeParser();
320: }
321:
322: private PageLayout findMainPage() {
323: for (int i = 0; i < PageLayoutList.size(); i++) {
324: PageLayout page = (PageLayout) PageLayoutList.elementAt(i);
325: if (page.getStartPage())
326: return page;
327: }
328: // we didn't find a main page!!
329: ExceptionUtil.reportException(new Exception(
330: "Main page not defined"));
331: return null;
332: }
333:
334: public String getMainPageLayoutName() {
335: PageLayout pl = findMainPage();
336: if (pl == null)
337: return "";
338: return pl.getName();
339: }
340:
341: public void outputPage(PageRequest req) {
342: PageGenerator pg = new PageGenerator(req);
343: pg.preparePageInfo();
344: /* generate both the full HTML page as well as the HTML Table data page;
345: The HTML table data page is subset of full HTML page excluding the
346: <head> & <body> tags so that it can be easily embedded into another HTML page
347: */
348: pg.generateHTMLPage();
349: pg.generateHTMLTableDataPage();
350: }
351:
352: public PageLayout getPageLayout(String PageName) {
353: for (int i = 0; i < PageLayoutList.size(); i++) {
354: PageLayout p = (PageLayout) PageLayoutList.elementAt(i);
355: if (p.getName().equalsIgnoreCase(PageName))
356: return p;
357: }
358: ExceptionUtil.reportException(new Exception("PageLayout "
359: + PageName + "not found"));
360: return null;
361: }
362: }
|