0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041: package org.netbeans.modules.visualweb.faces.dt_1_1.component.html;
0042:
0043: import java.io.File;
0044: import java.io.IOException;
0045: import java.io.PrintStream;
0046: import java.net.MalformedURLException;
0047: import java.net.URL;
0048: import java.sql.ResultSet;
0049: import java.sql.ResultSetMetaData;
0050: import java.sql.SQLException;
0051: import java.util.ArrayList;
0052: import java.util.List;
0053: import javax.faces.application.Application;
0054: import javax.faces.component.UIColumn;
0055: import javax.faces.component.UICommand;
0056: import javax.faces.component.UISelectItems;
0057: import javax.faces.component.html.HtmlCommandButton;
0058: import javax.faces.component.html.HtmlCommandLink;
0059: import javax.faces.component.html.HtmlMessage;
0060: import javax.faces.component.html.HtmlOutputText;
0061: import javax.faces.component.html.HtmlPanelGrid;
0062: import javax.faces.component.html.HtmlPanelGroup;
0063: import javax.faces.component.html.HtmlSelectOneMenu;
0064: import javax.faces.component.html.HtmlSelectOneRadio;
0065: import javax.faces.context.FacesContext;
0066: import javax.faces.el.ReferenceSyntaxException;
0067: import javax.faces.el.ValueBinding;
0068: import javax.sql.RowSet;
0069: import com.sun.rave.faces.data.DefaultSelectItemsArray;
0070: import com.sun.rave.faces.data.CachedRowSetDataModel;
0071: import org.netbeans.modules.visualweb.faces.dt.util.ComponentBundle;
0072: import com.sun.rave.designtime.DesignBean;
0073: import com.sun.rave.designtime.DesignContext;
0074: import com.sun.rave.designtime.DesignEvent;
0075: import com.sun.rave.designtime.DesignProperty;
0076: import com.sun.rave.designtime.Position;
0077: import com.sun.rave.designtime.faces.FacesDesignBean;
0078: import com.sun.rave.designtime.faces.FacesDesignContext;
0079:
0080: public class HtmlDataTableState {
0081:
0082: private static final ComponentBundle bundle = ComponentBundle
0083: .getBundle(HtmlDataTableState.class);
0084:
0085: public static final String DEFAULT_VAR_NAME = "currentRow"; //NOI18N
0086: private static final String COLUMN_ITEM_TEXT = bundle
0087: .getMessage("column"); //NOI18N
0088: private static final String JSFEL_START = "#{"; //NOI18N
0089: private static final String JSFEL_END = "}"; //NOI18N
0090: private static final String JSFEL_OPENQUOT = "['"; //NOI18N
0091: private static final String JSFEL_CLOSEQUOT = "']"; //NOI18N
0092: private static final String DOT = "."; //NOI18N
0093: private static final String ACTION_LIVE_EVENT = "action"; //NOI18N
0094: private static final String[] PAGING_HANDLER_SUFFIXES = {
0095: "_firstPageAction", "_previousPageAction",
0096: "_nextPageAction", "_lastPageAction" }; //NOI18N
0097:
0098: private static final String STYLE_CLASS_HEADER = "list-paging-header"; //NOI18N
0099: private static final String STYLE_CLASS_FOOTER = "list-paging-footer"; //NOI18N
0100:
0101: private static final String DEFAULT_FIRST_TEXT = "|<"; //NOI18N
0102: private static final String DEFAULT_PREVIOUS_TEXT = "<-"; //NOI18N
0103: private static final String DEFAULT_NEXT_TEXT = "->"; //NOI18N
0104: private static final String DEFAULT_LAST_TEXT = ">|"; //NOI18N
0105: private static final String DEFAULT_FIRST_URL = "resources/paging_first.gif"; //NOI18N
0106: private static final String DEFAULT_PREVIOUS_URL = "resources/paging_previous.gif"; //NOI18N
0107: private static final String DEFAULT_NEXT_URL = "resources/paging_next.gif"; //NOI18N
0108: private static final String DEFAULT_LAST_URL = "resources/paging_last.gif"; //NOI18N
0109: private static final String DEFAULT_FIRST_IMG = "paging_first.gif"; //NOI18N
0110: private static final String DEFAULT_PREVIOUS_IMG = "paging_previous.gif"; //NOI18N
0111: private static final String DEFAULT_NEXT_IMG = "paging_next.gif"; //NOI18N
0112: private static final String DEFAULT_LAST_IMG = "paging_last.gif"; //NOI18N
0113:
0114: static final String TOP = bundle.getMessage("top"); //NOI18N
0115: static final String BOTTOM = bundle.getMessage("bottom"); //NOI18N
0116: static final String TOP_AND_BOTTOM = bundle
0117: .getMessage("topAndBottom"); //NOI18N
0118: static final String BUTTON_TEXT = bundle.getMessage("navBtnText"); //NOI18N
0119: static final String BUTTON_IMAGE = bundle.getMessage("navBtnImage"); //NOI18N
0120: static final String BUTTON_NONE = bundle
0121: .getMessage("navBtnNotDispl"); //NOI18N
0122: static final String ALIGN_CENTER = bundle.getMessage("center"); //NOI18N
0123: static final String ALIGN_LEFT = bundle.getMessage("left"); //NOI18N
0124: static final String ALIGN_RIGHT = bundle.getMessage("right"); //NOI18N
0125:
0126: private DesignBean tableBean;
0127:
0128: public HtmlDataTableState(DesignBean tableBean) {
0129: this .tableBean = tableBean;
0130: loadState();
0131: }
0132:
0133: public DesignBean getTableBean() {
0134: return this .tableBean;
0135: }
0136:
0137: public static String maybeGenerateRowsetColumns(
0138: DesignBean tableBean, String valueExpr) {
0139: DesignContext context = tableBean.getDesignContext();
0140: if (context instanceof FacesDesignContext) {
0141: FacesDesignContext fcontext = (FacesDesignContext) context;
0142: Object o = fcontext.resolveBindingExpr(valueExpr);
0143: if (o instanceof RowSet) {
0144: // ok - we know the user has bound to a RowSet, so do the necessary "magic", and
0145: // return the value expr that points to the CachedRowSetDataModel
0146: RowSet rs = (RowSet) o;
0147: HtmlDataTableState state = new HtmlDataTableState(
0148: tableBean);
0149: state.setSourceInstance(rs);
0150: state.refreshColumnInfo();
0151: valueExpr = state.saveStateExceptModelValueExpr();
0152: }
0153: }
0154: return valueExpr;
0155: }
0156:
0157: /////////////////////////////////// CLASS STRUCTURES ///////////////////////////////////////////
0158:
0159: //////Columns tab///////
0160: //private String instanceName; //instance name to be persisted in source code (such as dataTable1) of the tableBean's underlying HtmlDataTable instance
0161: private DesignBean sourceBean; //the live bean chosen as the source of data for the table
0162: public String varName; //the value of the var attribute for this table in the JSP
0163: public ResultSetInfo rsinfo; //information about a ResultSet, if the sourceBean is of that type
0164: public DisplayInfo display = new DisplayInfo(); //information about the columns to be displayed
0165: private DesignBean savedSourceBean; //the sourceBean set by loadState
0166:
0167: ///////Paging tab///////
0168: public PagingInfo paging = new PagingInfo(); //information gathered from the Paging tab
0169:
0170: public void setSourceBean(DesignBean bean) {
0171: sourceBean = bean;
0172: }
0173:
0174: public void refreshColumnInfo() {
0175: display.clearColumns();
0176: if (getSourceInstance() instanceof ResultSet) {
0177: if (rsinfo == null) {
0178: rsinfo = new ResultSetInfo();
0179: }
0180: rsinfo.refreshColumns();
0181: for (int i = 0; i < rsinfo.getColumnCount(); i++) {
0182: display.addColumn(rsinfo.getColumn(i));
0183: }
0184: } else {
0185: rsinfo = null;
0186: display.addNewColumn();
0187: }
0188: }
0189:
0190: public DesignBean getSourceBean() {
0191: return sourceBean;
0192: }
0193:
0194: public void setSourceInstance(Object sourceInst) {
0195: DesignBean designBean = getDesignBeanForSourceInstance(sourceInst);
0196: setSourceBean(designBean);
0197: }
0198:
0199: public Object getSourceInstance() {
0200: return sourceBean == null ? null : sourceBean.getInstance();
0201: }
0202:
0203: public DesignBean getSavedSourceBean() {
0204: return savedSourceBean;
0205: }
0206:
0207: private DesignBean getDesignBeanForSourceInstance(Object sourceInst) {
0208: if (sourceInst == null) {
0209: return null;
0210: }
0211: DesignBean designBean = null;
0212: DesignContext[] contexts = tableBean.getDesignContext()
0213: .getProject().getDesignContexts();
0214: for (int i = 0; i < contexts.length; i++) {
0215: designBean = contexts[i].getBeanForInstance(sourceInst);
0216: if (designBean != null) {
0217: break;
0218: }
0219: }
0220: return designBean;
0221: }
0222:
0223: private String getStrippedSourceBeanValueRef() {
0224: if (sourceBean == null) {
0225: return null;
0226: }
0227: DesignContext context = sourceBean.getDesignContext();
0228: String outer = ((FacesDesignContext) context)
0229: .getReferenceName();
0230: return outer + DOT + sourceBean.getInstanceName();
0231: }
0232:
0233: public class ResultSetInfo {
0234: private List resultSetColumnList = new ArrayList();
0235:
0236: public void refreshColumns() {
0237: clearColumns();
0238: Object sourceInst = getSourceInstance();
0239: if (!(sourceInst instanceof ResultSet)) {
0240: return;
0241: }
0242: ResultSet rs = (ResultSet) sourceInst;
0243: try {
0244: ResultSetMetaData rsmd = rs.getMetaData();
0245: int cols = rsmd.getColumnCount();
0246: for (int c = 1; c <= cols; c++) {
0247: ResultSetColumn rsc = new ResultSetColumn();
0248: rsc.tableName = rsmd.getTableName(c);
0249: rsc.columnName = rsmd.getColumnName(c);
0250: //rsc.columnClassName = rsmd.getColumnClassName(c);
0251: //rsc.columnSqlType = rsmd.getColumnType(c);
0252: //rsc.columnSqlTypeName = rsmd.getColumnTypeName(c);
0253: addColumn(rsc);
0254: }
0255: } catch (Exception x) {
0256: System.err
0257: .println("HtmlDataTableState.ResultSetInfo.refreshColumns(): probable ResultSetMetaData problem:"); //NOI18N
0258: x.printStackTrace();
0259: }
0260: }
0261:
0262: public ResultSetColumn createColumn() {
0263: return new ResultSetColumn();
0264: }
0265:
0266: public void addColumn(ResultSetColumn rsc) {
0267: resultSetColumnList.add(rsc);
0268: }
0269:
0270: public void removeColumn(ResultSetColumn rsc) {
0271: resultSetColumnList.remove(rsc);
0272: }
0273:
0274: public void clearColumns() {
0275: resultSetColumnList.clear();
0276: }
0277:
0278: public ResultSetColumn[] getColumns() {
0279: return (ResultSetColumn[]) resultSetColumnList
0280: .toArray(new ResultSetColumn[resultSetColumnList
0281: .size()]);
0282: }
0283:
0284: public int getColumnCount() {
0285: return resultSetColumnList.size();
0286: }
0287:
0288: public ResultSetColumn getColumn(int index) {
0289: return (ResultSetColumn) resultSetColumnList.get(index);
0290: }
0291: }
0292:
0293: public class ResultSetColumn {
0294: public String tableName;
0295: public String columnName;
0296:
0297: //public String columnClassName;
0298: //public int columnSqlType;
0299: //public String columnSqlTypeName;
0300: public String toString() {
0301: if (tableName != null && tableName.length() > 0) {
0302: return tableName + DOT + columnName;
0303: } else {
0304: return columnName;
0305: }
0306: }
0307:
0308: public String getValueRef() {
0309: return JSFEL_START + varName + JSFEL_OPENQUOT + columnName
0310: + JSFEL_CLOSEQUOT + JSFEL_END;
0311: }
0312: }
0313:
0314: public class PagingInfo {
0315: //public boolean paging;
0316: public int rows;
0317:
0318: public String navigation = BUTTON_NONE;
0319: public boolean navOnTop;
0320: public boolean navOnBottom;
0321: public String align = ALIGN_CENTER;
0322:
0323: public boolean firstButton;
0324: public String firstButtonText = DEFAULT_FIRST_TEXT;
0325: public String firstButtonUrl = DEFAULT_FIRST_URL;
0326: public boolean previousButton;
0327: public String previousButtonText = DEFAULT_PREVIOUS_TEXT;
0328: public String previousButtonUrl = DEFAULT_PREVIOUS_URL;
0329: public boolean nextButton;
0330: public String nextButtonText = DEFAULT_NEXT_TEXT;
0331: public String nextButtonUrl = DEFAULT_NEXT_URL;
0332: public boolean lastButton;
0333: public String lastButtonText = DEFAULT_LAST_TEXT;
0334: public String lastButtonUrl = DEFAULT_LAST_URL;
0335: }
0336:
0337: public class DisplayInfo {
0338: private static final int MAX_DISPLAY_COLUMNS = 9999;
0339: private List displayColumnList = new ArrayList();
0340: private DisplayColumn[] savedColumns;
0341:
0342: public void addColumn(ResultSetColumn rsc) {
0343: DisplayColumn dc = new DisplayColumn();
0344: //let dc.columnInstanceName be null
0345: dc.compClassName = HtmlOutputText.class.getName();
0346: dc.compValueRef = rsc.getValueRef();
0347: dc.headerText = rsc.columnName;
0348: //let dc.footerText be null
0349: dc.itemText = rsc.toString();
0350: dc.hasResultSetColumnPeer = true;
0351: addColumn(dc);
0352: }
0353:
0354: public DisplayColumn addNewColumn() {
0355: DisplayColumn dc = new DisplayColumn();
0356: List names = new ArrayList();
0357: for (int i = 0; i < displayColumnList.size(); i++) {
0358: String aColumnInstanceName = ((DisplayColumn) displayColumnList
0359: .get(i)).columnInstanceName;
0360: if (aColumnInstanceName != null) {
0361: names.add(aColumnInstanceName);
0362: }
0363: }
0364: for (int i = 1; i < MAX_DISPLAY_COLUMNS; i++) {
0365: if (!names.contains(COLUMN_ITEM_TEXT + i)) {
0366: dc.columnInstanceName = COLUMN_ITEM_TEXT + i;
0367: break;
0368: }
0369: }
0370: dc.compClassName = HtmlOutputText.class.getName();
0371: //let dc.compValueRef be null
0372: dc.headerText = dc.columnInstanceName;
0373: //let dc.footerText be null
0374: dc.itemText = dc.columnInstanceName;
0375: addColumn(dc);
0376: return dc;
0377: }
0378:
0379: public DisplayColumn[] getColumns() {
0380: return (DisplayColumn[]) displayColumnList
0381: .toArray(new DisplayColumn[displayColumnList.size()]);
0382: }
0383:
0384: public void addColumn(DisplayColumn dc) {
0385: displayColumnList.add(dc);
0386: }
0387:
0388: public void removeColumn(DisplayColumn dc) {
0389: displayColumnList.remove(dc);
0390: }
0391:
0392: public void clearColumns() {
0393: displayColumnList.clear();
0394: }
0395:
0396: public int getColumnCount() {
0397: return displayColumnList.size();
0398: }
0399:
0400: public DisplayColumn getColumn(int index) {
0401: return (DisplayColumn) displayColumnList.get(index);
0402: }
0403:
0404: public boolean canMoveUp(DisplayColumn dc) {
0405: return displayColumnList.indexOf(dc) > 0;
0406: }
0407:
0408: public void moveColumnUp(DisplayColumn dc) {
0409: int idx = displayColumnList.indexOf(dc);
0410: if (idx > 0) {
0411: displayColumnList.remove(dc);
0412: displayColumnList.add(idx - 1, dc);
0413: }
0414: }
0415:
0416: public boolean canMoveDown(DisplayColumn dc) {
0417: int idx = displayColumnList.indexOf(dc);
0418: return idx > -1 && idx < displayColumnList.size() - 1;
0419: }
0420:
0421: public void moveColumnDown(DisplayColumn dc) {
0422: int idx = displayColumnList.indexOf(dc);
0423: if (idx > -1 && idx < displayColumnList.size() - 1) {
0424: displayColumnList.remove(dc);
0425: displayColumnList.add(idx + 1, dc);
0426: }
0427: }
0428:
0429: private void saveDisplayColumns() {
0430: savedColumns = getColumns();
0431: }
0432: }
0433:
0434: public class DisplayColumn {
0435: public DesignBean columnDesignBean; //live bean holding a UIColumn object
0436: public String columnInstanceName; //instance name of UIColumn in source code, like column1.
0437: //public String compInstanceName; //the field component instance's instance name in source code, like outputText2 (instance of type HtmlOutputText)
0438: public String compClassName; //like javax.faces.component.html.HtmlOutputText or other UIComponent subclass. used to create a DesignBean to wrap the component
0439: public String compValueRef; //like #{currentRow['PERSONID']} or #{currentRow.donkey}
0440: public String compSIValueRef; //if comp class is HtmlSelectOneMenu, then the value attribute of its select items is this jsf-el expression
0441: public String headerText;
0442: //public boolean headerLink; //whether header text is an hypertext link to sort that column
0443: public String footerText;
0444: public String itemText; //what gets displayed in the list
0445: public boolean hasResultSetColumnPeer;
0446:
0447: public String toString() {
0448: return itemText;
0449: }
0450: }
0451:
0452: private String getStrippedJsfEL(String valueRef) {
0453: if (valueRef == null) {
0454: return null;
0455: }
0456: if (!valueRef.startsWith(JSFEL_START)
0457: || !valueRef.endsWith(JSFEL_END)) {
0458: return valueRef;
0459: }
0460: return valueRef.substring(JSFEL_START.length(), valueRef
0461: .indexOf(JSFEL_END));
0462: }
0463:
0464: private String getTextFromDesignProperty(DesignProperty vp) {
0465: return vp == null ? null : vp.getValueSource();
0466: }
0467:
0468: boolean isJsfELSyntax(String s) {
0469: if (s == null) {
0470: return false;
0471: }
0472: return s.startsWith(JSFEL_START) && s.endsWith(JSFEL_END);
0473: }
0474:
0475: boolean validateJsfEL(String s) {
0476: //right now it makes sense for the dialog to relax its restrictions, since QE has found cases where
0477: //this strategy is prohibitively restrictive, i.e., it returns false though the expression would work at runtime.
0478: //for instance, see 6183023
0479: FacesDesignContext flc = (FacesDesignContext) tableBean
0480: .getDesignContext();
0481: FacesContext facesContext = flc.getFacesContext();
0482: Application facesApp = facesContext.getApplication();
0483: try {
0484: ValueBinding vb = facesApp.createValueBinding(s);
0485: Object result = vb.getValue(facesContext);
0486: return true;
0487: } catch (ReferenceSyntaxException rse) {
0488: return false;
0489: }
0490: /*
0491: //tableBean.getDesignContext() must be an instance of FacesDesignContext. otherwise it makes no sense to call this method.
0492: if (!isJsfELSyntax(s)) {
0493: return false;
0494: }
0495:
0496: if (!(tableBean.getDesignContext() instanceof FacesDesignContext)) {
0497: return false;
0498: }
0499: FacesDesignContext flc = (FacesDesignContext)tableBean.getDesignContext();
0500: FacesContext facesContext = flc.getFacesContext();
0501: Application facesApp = facesContext.getApplication();
0502: //if sourceInstance is a ResultSet and is relative to varName, then we know the absolute expression and can use it for more stringent validation
0503: if (getSourceInstance() instanceof ResultSet && s.startsWith(JSFEL_START + varName)) {
0504: DesignContext sbContext = sourceBean.getDesignContext();
0505: s = JSFEL_START + ((FacesDesignContext)sbContext).getReferenceName() + DOT +
0506: sourceBean.getInstanceName() + DOT + getStrippedJsfEL(s) + JSFEL_END;
0507: }
0508: try {
0509: ValueBinding vb = facesApp.createValueBinding(s);
0510: Object result = vb.getValue(facesContext);
0511: return true;
0512: } catch (EvaluationException ee) {
0513: return false;
0514: }
0515: */
0516: }
0517:
0518: private DesignEvent getActionEvent(DesignBean commandBean) {
0519: DesignEvent[] events = commandBean.getEvents();
0520: for (int e = 0; e < events.length; e++) {
0521: if (ACTION_LIVE_EVENT.equals(events[e].getEventDescriptor()
0522: .getName())) {
0523: return events[e];
0524: }
0525: }
0526: return null;
0527: }
0528:
0529: private DesignBean[] getPagingComponents(DesignBean panel) {
0530: //facet can be null
0531: DesignBean[] pagingComponents = new DesignBean[PAGING_HANDLER_SUFFIXES.length]; //a place to put the paging buttons or links for the panel
0532: if (panel == null) {
0533: return pagingComponents;
0534: }
0535: Object panelInstance = panel.getInstance();
0536: if (!(panelInstance instanceof HtmlPanelGrid || panelInstance instanceof HtmlPanelGroup)) {
0537: return pagingComponents;
0538: }
0539: boolean panelContainsPagingComponents = false;
0540: DesignBean[] children = panel.getChildBeans();
0541: childrenLoop: for (int i = 0; i < children.length; i++) { //go through the components within the panel
0542:
0543: if (!(children[i].getInstance() instanceof UICommand)) {
0544: continue; //if this component is not a button or link, go to the next component
0545: }
0546: DesignEvent actionEvent = getActionEvent(children[i]); //get the action event associated with this component
0547: if (actionEvent == null) {
0548: continue; //go to the next component
0549: }
0550: String actionEventHandler = actionEvent.getHandlerName(); //the handler method name for the action event
0551: if (actionEventHandler == null) {
0552: continue; //go to the next component
0553: }
0554: for (int j = 0; j < PAGING_HANDLER_SUFFIXES.length; j++) {
0555: //if we already have a component for this paging handler suffix, go to the next suffix
0556: if (pagingComponents[j] != null) {
0557: continue;
0558: }
0559: if (actionEventHandler.equals(tableBean
0560: .getInstanceName()
0561: + PAGING_HANDLER_SUFFIXES[j])) {
0562: //children[i]'s action handler method is the paging handler for this suffix
0563: pagingComponents[j] = children[i];
0564: panelContainsPagingComponents = true;
0565: continue childrenLoop;
0566: }
0567: }
0568: }
0569: if (panelContainsPagingComponents) {
0570: if (panelInstance instanceof HtmlPanelGroup) {
0571: DesignProperty panelStyleProp = panel
0572: .getProperty("style"); //NOI18N
0573: if (panelStyleProp != null) {
0574: String panelStyle = panelStyleProp.getValueSource();
0575: if (panelStyle != null) {
0576: String patternPrefix = ".*?text-align\\s*:\\s*"; //NOI18N
0577: if (panelStyle.matches(patternPrefix + "left" //NOI18N
0578: )) {
0579: paging.align = ALIGN_LEFT;
0580: } else if (panelStyle.matches(patternPrefix
0581: + "center" //NOI18N
0582: )) {
0583: paging.align = ALIGN_CENTER;
0584: } else if (panelStyle.matches(patternPrefix
0585: + "right" //NOI18N
0586: )) {
0587: paging.align = ALIGN_RIGHT;
0588: }
0589: }
0590: }
0591: }
0592: }
0593: return pagingComponents;
0594: }
0595:
0596: private void setBasicPagingVariables(DesignBean[] pagingComponents,
0597: String facetStr) {
0598: //find out if there's at least one paging component for this facet. pagingComponents should not be null.
0599: boolean atLeastOne = false;
0600: for (int j = 0; j < pagingComponents.length; j++) {
0601: if (pagingComponents[j] != null) {
0602: atLeastOne = true;
0603: break;
0604: }
0605: }
0606: //set paging variables
0607: if (atLeastOne) {
0608: if ("header".equals(facetStr)) { //NOI18N
0609: paging.navOnTop = true;
0610: } else {
0611: paging.navOnBottom = true;
0612: }
0613: }
0614: }
0615:
0616: ////////////////////////////////////////////////////////////////////////////////////////////////
0617:
0618: public void loadState() {
0619: try {
0620: ////set instance vars
0621: //instanceName = tableBean.getInstanceName();
0622: Object sourceInst = tableBean.getProperty("value")
0623: .getValue(); //NOI18N
0624: if (sourceInst instanceof CachedRowSetDataModel) {
0625: sourceInst = ((CachedRowSetDataModel) sourceInst)
0626: .getWrappedData();
0627: }
0628: sourceBean = getDesignBeanForSourceInstance(sourceInst); //do not call setSourceBean(...) here! use sourceBean = ...!
0629: savedSourceBean = sourceBean;
0630: varName = tableBean.getProperty("var").getValueSource(); //NOI18N
0631: if (varName == null || varName.length() == 0) {
0632: varName = DEFAULT_VAR_NAME;
0633:
0634: //paging stuff
0635: }
0636: Object pagingRows = tableBean.getProperty("rows")
0637: .getValue(); //NOI18N
0638: if (pagingRows != null) {
0639: paging.rows = ((Integer) pagingRows).intValue(); //number of rows per "page" if paging is enabled on this table
0640: }
0641: if (tableBean instanceof FacesDesignBean) {
0642: paging.align = ALIGN_CENTER;
0643: paging.navOnTop = false;
0644: paging.navOnBottom = false;
0645: FacesDesignBean ftableBean = (FacesDesignBean) tableBean;
0646: DesignBean header = ftableBean.getFacet("header"); //can be null //NOI18N
0647: DesignBean footer = ftableBean.getFacet("footer"); //can be null //NOI18N
0648: DesignBean[] headerPagingComponents = getPagingComponents(header); //won't be null
0649: setBasicPagingVariables(headerPagingComponents,
0650: "header"); //NOI18N
0651: DesignBean[] footerPagingComponents = getPagingComponents(footer); //won't be null
0652: setBasicPagingVariables(footerPagingComponents,
0653: "footer"); //NOI18N
0654:
0655: //merge the header and footer paging component arrays
0656: DesignBean[] mergedPagingComponents = headerPagingComponents;
0657: headerPagingComponents = null;
0658: for (int i = 0; i < footerPagingComponents.length; i++) {
0659: if (footerPagingComponents[i] != null) {
0660: mergedPagingComponents[i] = footerPagingComponents[i];
0661: }
0662: }
0663: footerPagingComponents = null;
0664:
0665: /*
0666: System.err.println("HtmlDataTableState.loadState: mergedPagingComponents:"); //NOI18N
0667: for (int m = 0; m < mergedPagingComponents.length; m++) {
0668: System.err.println("\t" + m + ":" + mergedPagingComponents[m] + "!"); //NOI18N
0669: }
0670: */
0671:
0672: paging.navigation = BUTTON_NONE;
0673: if (mergedPagingComponents[0] != null) {
0674: paging.firstButton = true;
0675: //we have a button. upgrade to BUTTON_TEXT.
0676: paging.navigation = BUTTON_TEXT;
0677: String buttonText = (String) mergedPagingComponents[0]
0678: .getProperty("value").getValueSource(); //NOI18N
0679: paging.firstButtonText = buttonText == null
0680: || buttonText.length() < 1 ? DEFAULT_FIRST_TEXT
0681: : buttonText;
0682: String buttonImageUrl = (String) mergedPagingComponents[0]
0683: .getProperty("image").getValueSource(); //NOI18N
0684: boolean buttonImageUrlEmpty = buttonImageUrl == null
0685: || buttonImageUrl.length() < 1;
0686: paging.firstButtonUrl = buttonImageUrlEmpty ? DEFAULT_FIRST_URL
0687: : buttonImageUrl;
0688: if (!buttonImageUrlEmpty) {
0689: paging.navigation = BUTTON_IMAGE;
0690: }
0691: } else {
0692: paging.firstButton = false;
0693: }
0694: if (mergedPagingComponents[1] != null) {
0695: paging.previousButton = true;
0696: //we have a button. so if paging.navigation was BUTTON_NONE, upgrade to BUTTON_TEXT.
0697: if (BUTTON_NONE.equals(paging.navigation)) {
0698: paging.navigation = BUTTON_TEXT;
0699: }
0700: String buttonText = (String) mergedPagingComponents[1]
0701: .getProperty("value").getValueSource(); //NOI18N
0702: paging.previousButtonText = buttonText == null
0703: || buttonText.length() < 1 ? DEFAULT_PREVIOUS_TEXT
0704: : buttonText;
0705: String buttonImageUrl = (String) mergedPagingComponents[1]
0706: .getProperty("image").getValueSource(); //NOI18N
0707: boolean buttonImageUrlEmpty = buttonImageUrl == null
0708: || buttonImageUrl.length() < 1;
0709: paging.previousButtonUrl = buttonImageUrlEmpty ? DEFAULT_PREVIOUS_URL
0710: : buttonImageUrl;
0711: if (!buttonImageUrlEmpty) {
0712: paging.navigation = BUTTON_IMAGE;
0713: }
0714: } else {
0715: paging.previousButton = false;
0716: }
0717: if (mergedPagingComponents[2] != null) {
0718: paging.nextButton = true;
0719: if (BUTTON_NONE.equals(paging.navigation)) {
0720: paging.navigation = BUTTON_TEXT;
0721: }
0722: String buttonText = (String) mergedPagingComponents[2]
0723: .getProperty("value").getValueSource(); //NOI18N
0724: paging.nextButtonText = buttonText == null
0725: || buttonText.length() < 1 ? DEFAULT_NEXT_TEXT
0726: : buttonText;
0727: String buttonImageUrl = (String) mergedPagingComponents[2]
0728: .getProperty("image").getValueSource(); //NOI18N
0729: boolean buttonImageUrlEmpty = buttonImageUrl == null
0730: || buttonImageUrl.length() < 1;
0731: paging.nextButtonUrl = buttonImageUrlEmpty ? DEFAULT_NEXT_URL
0732: : buttonImageUrl;
0733: if (!buttonImageUrlEmpty) {
0734: paging.navigation = BUTTON_IMAGE;
0735: }
0736: } else {
0737: paging.nextButton = false;
0738: }
0739: if (mergedPagingComponents[3] != null) {
0740: paging.lastButton = true;
0741: if (BUTTON_NONE.equals(paging.navigation)) {
0742: paging.navigation = BUTTON_TEXT;
0743: }
0744: String buttonText = (String) mergedPagingComponents[3]
0745: .getProperty("value").getValueSource(); //NOI18N
0746: paging.lastButtonText = buttonText == null
0747: || buttonText.length() < 1 ? DEFAULT_LAST_TEXT
0748: : buttonText;
0749: String buttonImageUrl = (String) mergedPagingComponents[3]
0750: .getProperty("image").getValueSource(); //NOI18N
0751: boolean buttonImageUrlEmpty = buttonImageUrl == null
0752: || buttonImageUrl.length() < 1;
0753: paging.lastButtonUrl = buttonImageUrlEmpty ? DEFAULT_LAST_URL
0754: : buttonImageUrl;
0755: if (!buttonImageUrlEmpty) {
0756: paging.navigation = BUTTON_IMAGE;
0757: }
0758: } else {
0759: paging.lastButton = false;
0760: }
0761: }
0762: loadColumnState();
0763: } catch (Exception x) {
0764: System.err
0765: .println("error in HtmlDataTableState.loadState():"); //NOI18N
0766: x.printStackTrace();
0767: //System.err.println("dumping state of HtmlDataTableState:"); //NOI18N
0768: //dumpState(System.err);
0769: }
0770: }
0771:
0772: void loadColumnState() {
0773: try {
0774: Object sourceInst = getSourceInstance();
0775:
0776: //update rsinfo if applicable
0777: if (sourceInst instanceof ResultSet) {
0778: if (rsinfo == null) {
0779: rsinfo = new ResultSetInfo();
0780: }
0781: rsinfo.refreshColumns();
0782: } else {
0783: rsinfo = null;
0784: }
0785:
0786: //update display instance variable
0787: display.clearColumns();
0788: DesignBean[] uicolumns = tableBean.getChildBeans();
0789: for (int i = 0; uicolumns != null && i < uicolumns.length; i++) {
0790: if (!(uicolumns[i].getInstance() instanceof UIColumn)) {
0791: continue;
0792: }
0793: DisplayColumn dc = new DisplayColumn();
0794: dc.columnDesignBean = uicolumns[i];
0795: dc.columnInstanceName = uicolumns[i].getInstanceName();
0796: DesignBean[] comps = uicolumns[i].getChildBeans();
0797:
0798: DesignBean header = null;
0799: DesignBean footer = null;
0800:
0801: // get the header and footer text from the facets
0802: if (uicolumns[i] instanceof FacesDesignBean) {
0803: FacesDesignBean flb = (FacesDesignBean) uicolumns[i];
0804: header = flb.getFacet("header"); //NOI18N
0805: if (header != null
0806: && header.getInstance() instanceof HtmlOutputText) {
0807: DesignProperty vp = header.getProperty("value"); //NOI18N
0808: dc.headerText = getTextFromDesignProperty(vp);
0809: }
0810: footer = flb.getFacet("footer"); //NOI18N
0811: if (footer != null
0812: && footer.getInstance() instanceof HtmlOutputText) {
0813: DesignProperty vp = footer.getProperty("value"); //NOI18N
0814: dc.footerText = getTextFromDesignProperty(vp);
0815: }
0816: }
0817:
0818: if (comps != null && comps.length >= 1) {
0819: DesignBean comp = null;
0820: for (int c = 0; c < comps.length; c++) {
0821: if (comps[c] != null && comps[c] != header
0822: && comps[c] != footer) {
0823: comp = comps[c];
0824: break;
0825: }
0826: }
0827: if (comp != null) {
0828: //dc.compInstanceName = comp.getInstanceName();
0829: dc.compClassName = comp.getInstance()
0830: .getClass().getName();
0831: DesignProperty valProp = comp
0832: .getProperty("value"); //NOI18N
0833: dc.compValueRef = valProp != null ? valProp
0834: .getValueSource() : null; //NOI18N
0835: if (dc.compClassName
0836: .equals(HtmlSelectOneMenu.class
0837: .getName())
0838: || dc.compClassName
0839: .equals(HtmlSelectOneRadio.class
0840: .getName())) {
0841: DesignBean[] compChildren = comp
0842: .getChildBeans();
0843: if (compChildren != null
0844: && compChildren.length > 0) {
0845: if (compChildren[0] != null
0846: && (compChildren[0]
0847: .getInstance() instanceof UISelectItems)) {
0848: DesignProperty siValueProp = compChildren[0]
0849: .getProperty("value"); //NOI18N
0850: if (siValueProp != null) {
0851: dc.compSIValueRef = siValueProp
0852: .getValueSource();
0853: }
0854: }
0855: }
0856: } else if (dc.compClassName
0857: .equals(HtmlCommandLink.class.getName())) {
0858: DesignBean[] compChildren = comp
0859: .getChildBeans();
0860: if (compChildren != null
0861: && compChildren.length > 0) {
0862: if (compChildren[0] != null
0863: && (compChildren[0]
0864: .getInstance() instanceof HtmlOutputText)) {
0865: DesignProperty childValueProp = compChildren[0]
0866: .getProperty("value"); //NOI18N
0867: if (childValueProp != null) {
0868: dc.compValueRef = childValueProp
0869: .getValueSource();
0870: }
0871: }
0872: }
0873: }
0874: }
0875: }
0876:
0877: //set dc.itemText
0878: if (sourceInst instanceof ResultSet
0879: && dc.compValueRef != null) {
0880: ResultSetColumn[] rsca = rsinfo.getColumns();
0881: for (int j = 0; j < rsca.length; j++) {
0882: if (dc.compValueRef.equals(rsca[j]
0883: .getValueRef())) {
0884: dc.itemText = rsca[j].toString();
0885: dc.hasResultSetColumnPeer = true;
0886: break;
0887: }
0888: }
0889: }
0890: if (dc.itemText == null) {
0891: dc.itemText = dc.columnInstanceName;
0892: }
0893:
0894: display.addColumn(dc);
0895: }
0896:
0897: display.saveDisplayColumns();
0898: } catch (Exception x) {
0899: System.err
0900: .println("error in HtmlDataTableState.loadColumnState():"); //NOI18N
0901: x.printStackTrace();
0902: //System.err.println("dumping state of HtmlDataTableState:"); //NOI18N
0903: //dumpState(System.err);
0904: }
0905: }
0906:
0907: protected boolean dontSaveModelValueExpr = false;
0908: protected String modelValueExpr = null;
0909:
0910: public String saveStateExceptModelValueExpr() {
0911: this .dontSaveModelValueExpr = true;
0912: saveState();
0913: this .dontSaveModelValueExpr = false;
0914: return this .modelValueExpr;
0915: }
0916:
0917: public void saveState() {
0918: //System.err.println("in HtmlDataTableState.saveState(): dumping state of HtmlDataTableState:"); //NOI18N
0919: //dumpState(System.err);
0920:
0921: DesignContext context = tableBean.getDesignContext();
0922: String outer = ((FacesDesignContext) context)
0923: .getReferenceName();
0924: FacesDesignContext flc = null;
0925: if (context instanceof FacesDesignContext) {
0926: flc = (FacesDesignContext) context;
0927: }
0928:
0929: DisplayColumn[] dca = display.getColumns();
0930:
0931: /*
0932: //copy over columnDesignBean from savedColumns to corresponding display columns as needed
0933: if (sourceBean == savedSourceBean && getSourceInstance() instanceof ResultSet) {
0934: for (int d = 0; d < dca.length; d++) {
0935: DisplayColumn dc = dca[d];
0936: if (dc == null || dc.columnDesignBean != null || dc.compValueRef == null) continue;
0937: DisplayColumn[] sca = display.savedColumns;
0938: for (int s = 0; s < sca.length; s++) {
0939: DisplayColumn sc = sca[s];
0940: if (sc == null) continue; //just defensive
0941: if (dc.compValueRef.equals(sc.compValueRef)) {
0942: dc.columnDesignBean = sc.columnDesignBean;
0943: }
0944: }
0945: }
0946: }
0947: */
0948:
0949: //nuke just the deleted columns (kids)
0950: DesignBean[] kids = tableBean.getChildBeans();
0951: for (int k = 0; kids != null && k < kids.length; k++) {
0952: DesignBean kid = kids[k];
0953: if (kid == null) {
0954: continue;
0955: }
0956: boolean keep = false;
0957: //go through display columns. keep this kid if we need it.
0958: for (int d = 0; d < dca.length; d++) {
0959: DisplayColumn dc = dca[d];
0960: if (kid == dc.columnDesignBean) {
0961: keep = true;
0962: break;
0963: }
0964: }
0965: if (!keep) {
0966: context.deleteBean(kid);
0967: }
0968: }
0969:
0970: /*
0971: * also nuke the facets. Note: This will irretrievably nuke any components the user has hand-coded in the facets!
0972: * the alternative is to make getPagingComponents return something that holds more than 4 buttons/links.
0973: * (For instance, there might be 10 buttons in the facet with 3 of them having the action event handler method dataTable1_previousPageAction.)
0974: * and then only nuke the *paging* components in the facet and then the whole facet only if there are no components left
0975: */
0976: if (tableBean instanceof FacesDesignBean) {
0977: DesignBean facet = ((FacesDesignBean) tableBean)
0978: .getFacet("header"); //NOI18N
0979: if (facet != null) {
0980: context.deleteBean(facet);
0981: }
0982: facet = ((FacesDesignBean) tableBean).getFacet("footer"); //NOI18N
0983: if (facet != null) {
0984: context.deleteBean(facet);
0985: //System.err.println("HtmlDataTableState.saveState: header exists?: " + ((FacesDesignBean)tableBean).getFacet("header")); //NOI18N
0986: //System.err.println("HtmlDataTableState.saveState: footer exists?: " + ((FacesDesignBean)tableBean).getFacet("footer")); //NOI18N
0987: }
0988: }
0989:
0990: // now create new children...
0991: for (int i = 0; i < dca.length; i++) {
0992: DisplayColumn dc = dca[i];
0993: DesignBean uicolumn = dc.columnDesignBean;
0994: if (uicolumn == null) {
0995: uicolumn = context.createBean(UIColumn.class.getName(),
0996: tableBean, new Position(i));
0997: uicolumn.setInstanceName(dc.columnInstanceName, true);
0998: } else {
0999: context.moveBean(uicolumn, tableBean, new Position(i));
1000: }
1001:
1002: DesignBean comp = null;
1003: DesignBean header = null;
1004: DesignBean footer = null;
1005:
1006: if (uicolumn instanceof FacesDesignBean) {
1007: FacesDesignBean fuicolumn = (FacesDesignBean) uicolumn;
1008: header = fuicolumn.getFacet("header"); //NOI18N
1009: footer = fuicolumn.getFacet("footer"); //NOI18N
1010: }
1011:
1012: DesignBean[] comps = uicolumn.getChildBeans();
1013: for (int c = 0; comps != null && c < comps.length; c++) {
1014: if (comps[c] != null && comps[c] != header
1015: && comps[c] != footer) {
1016: comp = comps[c];
1017: break;
1018: }
1019: }
1020:
1021: // if we have a first comp of the wrong type, wipe it out
1022: if (comp != null) {
1023: Object compInstance = comp.getInstance();
1024: if (compInstance == null
1025: || !compInstance.getClass().getName().equals(
1026: dc.compClassName)) {
1027: //first comp of wrong type. wipe it out.
1028: context.deleteBean(comp);
1029: comp = null;
1030: }
1031: }
1032:
1033: if (comp == null) {
1034: if (dc.compClassName == null) {
1035: dc.compClassName = HtmlOutputText.class.getName();
1036: }
1037: comp = context.createBean(dc.compClassName, uicolumn,
1038: new Position(0));
1039: if (dc.compClassName.equals(HtmlSelectOneMenu.class
1040: .getName())
1041: || dc.compClassName
1042: .equals(HtmlSelectOneRadio.class
1043: .getName())) {
1044: DesignBean selectitems = context.createBean(
1045: UISelectItems.class.getName(), comp, null);
1046: selectitems.setInstanceName(comp.getInstanceName()
1047: + "SelectItems", true); //NOI18N
1048: DesignBean items = context.createBean(
1049: DefaultSelectItemsArray.class.getName(),
1050: null, null);
1051: items.setInstanceName(comp.getInstanceName()
1052: + "DefaultItems", true); //NOI18N
1053: selectitems
1054: .getProperty("value")
1055: .setValueSource(JSFEL_START + outer + DOT + //NOI18N
1056: items.getInstanceName() + JSFEL_END); //NOI18N
1057: } else if (dc.compClassName
1058: .equals(HtmlCommandLink.class.getName())) {
1059: DesignBean childText = comp.getDesignContext()
1060: .createBean(HtmlOutputText.class.getName(),
1061: comp, null);
1062: childText.setInstanceName(comp.getInstanceName()
1063: + "Text", true); //NOI18N
1064: } else if (dc.compClassName.equals(HtmlMessage.class
1065: .getName())) {
1066: comp.getProperty("for").setValue(""); //NOI18N
1067: comp.getProperty("showDetail").setValue(
1068: Boolean.FALSE); //NOI18N
1069: comp.getProperty("showSummary").setValue(
1070: Boolean.TRUE); //NOI18N
1071: comp.getProperty("infoClass").setValue(
1072: "infoMessage"); // NOI18N
1073: comp.getProperty("warnClass").setValue(
1074: "warnMessage"); // NOI18N
1075: comp.getProperty("errorClass").setValue(
1076: "errorMessage"); // NOI18N
1077: comp.getProperty("fatalClass").setValue(
1078: "fatalMessage"); // NOI18N
1079: }
1080: }
1081:
1082: DesignProperty valProp = comp.getProperty("value"); //NOI18N
1083: if (dc.compClassName
1084: .equals(HtmlCommandLink.class.getName())) {
1085: if (valProp != null) {
1086: valProp.unset();
1087: }
1088: DesignBean childText = null; //the HtmlOutputText child of the link action, if it exists
1089: DesignBean[] compChildren = comp.getChildBeans();
1090: if (compChildren != null && compChildren.length > 0) {
1091: if (compChildren[0] != null
1092: && (compChildren[0].getInstance() instanceof HtmlOutputText)) {
1093: childText = compChildren[0];
1094: }
1095: }
1096: if (childText != null) {
1097: String childTextValue = bundle
1098: .getMessage("linkAction"); //NOI18N
1099: if (dc.compValueRef != null) {
1100: childTextValue = dc.compValueRef;
1101: }
1102: if (isJsfELSyntax(childTextValue)) {
1103: childText.getProperty("value").setValueSource(
1104: childTextValue); //NOI18N
1105: } else {
1106: childText.getProperty("value").setValue(
1107: childTextValue); //NOI18N
1108: }
1109: }
1110: } else if (dc.compValueRef == null
1111: || dc.compValueRef.length() == 0) {
1112: if (valProp != null) {
1113: valProp.unset();
1114: }
1115: } else {
1116: if (valProp != null) {
1117: if (isJsfELSyntax(dc.compValueRef)) {
1118: valProp.setValueSource(dc.compValueRef); //NOI18N
1119: } else {
1120: valProp.setValue(dc.compValueRef);
1121: }
1122: }
1123: }
1124:
1125: // setup the header and footer facets
1126: if (header == null && dc.headerText != null && flc != null) {
1127: if (flc.canCreateFacet("header", HtmlOutputText.class
1128: .getName(), uicolumn)) { //NOI18N
1129: header = flc.createFacet("header",
1130: HtmlOutputText.class.getName(), uicolumn); //NOI18N
1131: }
1132: }
1133: if (header != null) {
1134: DesignProperty vp = header.getProperty("value"); //NOI18N
1135: if (vp != null) {
1136: if (isJsfELSyntax(dc.headerText)) {
1137: vp.setValueSource(dc.headerText);
1138: } else {
1139: vp.setValue(dc.headerText);
1140: }
1141: }
1142: }
1143: if (footer == null && dc.footerText != null && flc != null) {
1144: if (flc.canCreateFacet("footer", HtmlOutputText.class
1145: .getName(), uicolumn)) { //NOI18N
1146: footer = flc.createFacet("footer",
1147: HtmlOutputText.class.getName(), uicolumn); //NOI18N
1148: }
1149: }
1150: if (footer != null) {
1151: DesignProperty vp = footer.getProperty("value"); //NOI18N
1152: if (vp != null) {
1153: if (isJsfELSyntax(dc.footerText)) {
1154: vp.setValueSource(dc.footerText);
1155: } else {
1156: vp.setValue(dc.footerText);
1157: }
1158: }
1159: }
1160: }
1161:
1162: // If the source instance is a RowSet ...
1163: DesignBean dm = null;
1164: if (sourceBean != null) {
1165: Object sourceInst = sourceBean.getInstance();
1166: if (sourceInst instanceof RowSet) {
1167:
1168: // Create or replace the corresponding datamodel
1169: DesignContext lc = tableBean.getDesignContext();
1170: String dmName = tableBean.getInstanceName() + "Model"; //NOI18N
1171: dm = lc.getBeanByName(dmName);
1172: if (dm != null) {
1173: dm.getDesignContext().deleteBean(dm);
1174: }
1175: dm = lc.createBean(CachedRowSetDataModel.class
1176: .getName(), null, null);
1177: dm.setInstanceName(dmName);
1178:
1179: // Configure properties on the new datamodel
1180: dm.getProperty("cachedRowSet").setValue(
1181: sourceBean.getInstance()); // NOI18N
1182:
1183: }
1184: }
1185:
1186: //now properties
1187: //System.err.println("HtmlTableDataState.saveState: getStrippedSourceBeanValueRef():" + getStrippedSourceBeanValueRef() + "!"); //NOI18N
1188: if (sourceBean == null) { // No value binding at all
1189: if (dontSaveModelValueExpr) {
1190: this .modelValueExpr = null;
1191: } else {
1192: tableBean.getProperty("value").unset(); //NOI18N
1193: }
1194: } else if (dm != null) { // Bound to a RowSet
1195: if (dontSaveModelValueExpr) {
1196: DesignContext dmc = dm.getDesignContext();
1197: if (dmc instanceof FacesDesignContext) {
1198: this .modelValueExpr = JSFEL_START
1199: + ((FacesDesignContext) dmc)
1200: .getReferenceName() + DOT
1201: + dm.getInstanceName() + JSFEL_END;
1202: } else {
1203: this .modelValueExpr = JSFEL_START
1204: + dmc.getDisplayName() + DOT
1205: + dm.getInstanceName() + JSFEL_END;
1206: }
1207: } else {
1208: tableBean.getProperty("value").setValue(
1209: dm.getInstance()); // NOI18N
1210: }
1211: } else { // Bound to something else
1212: String vref = JSFEL_START + getStrippedSourceBeanValueRef()
1213: + JSFEL_END;
1214: if (dontSaveModelValueExpr) {
1215: this .modelValueExpr = vref;
1216: } else {
1217: if (isJsfELSyntax(vref)) {
1218: tableBean.getProperty("value").setValueSource(vref); //NOI18N
1219: } else {
1220: tableBean.getProperty("value").setValue(vref); //NOI18N
1221: }
1222: }
1223: }
1224: savedSourceBean = sourceBean;
1225: display.saveDisplayColumns();
1226: tableBean.getProperty("var").setValue(varName); //NOI18N
1227: try {
1228: tableBean.getProperty("rows").setValue(
1229: new Integer(paging.rows)); //NOI18N
1230: } catch (Exception x) {
1231: }
1232:
1233: //now navigation buttons
1234: boolean atLeastOneButtonRequested = paging.firstButton
1235: || paging.previousButton || paging.nextButton
1236: || paging.lastButton;
1237: if (paging.rows > 0
1238: && (BUTTON_TEXT.equals(paging.navigation) || BUTTON_IMAGE
1239: .equals(paging.navigation))
1240: && atLeastOneButtonRequested) {
1241: if (paging.navOnTop) {
1242: createNavPanel("header"); //NOI18N
1243: }
1244: if (paging.navOnBottom) {
1245: createNavPanel("footer"); //NOI18N
1246: }
1247: }
1248: }
1249:
1250: /**
1251: * Create a facet as a DesignBean as well as all buttons within the facet and set the buttons' action event handler method name and source code. Called by saveState.
1252: */
1253: private void createNavPanel(String facetStr) {
1254: DesignContext context = tableBean.getDesignContext();
1255: FacesDesignContext flc = null;
1256: if (context instanceof FacesDesignContext) {
1257: flc = (FacesDesignContext) context;
1258: }
1259: if (!flc.canCreateFacet(facetStr,
1260: HtmlPanelGrid.class.getName(), tableBean)) {
1261: System.err
1262: .println("HtmlTableDataState.createNavPanel: error: could not create facet of type "
1263: + //NOI18N
1264: facetStr + " for tableBean " + tableBean); //NOI18N
1265: return;
1266: }
1267:
1268: //create a facet
1269: DesignBean facet = flc.createFacet(facetStr,
1270: HtmlPanelGroup.class.getName(), tableBean);
1271:
1272: //give it a style
1273: DesignProperty facetProp = facet.getProperty("style"); //NOI18N
1274: if (facetProp != null) {
1275: String stylePrefix = "display: block; text-align: "; //NOI18N
1276: String alignValue = "center"; //NOI18N
1277: if (ALIGN_LEFT.equals(paging.align)) {
1278: alignValue = "left"; //NOI18N
1279: } else if (ALIGN_RIGHT.equals(paging.align)) {
1280: alignValue = "right"; //NOI18N
1281: }
1282: facetProp.setValue(stylePrefix + alignValue);
1283:
1284: }
1285: //set the style class
1286: facetProp = facet.getProperty("styleClass"); //NOI18N
1287: if (facetProp != null) {
1288: facetProp
1289: .setValue("footer".equals(facetStr) ? STYLE_CLASS_FOOTER
1290: : STYLE_CLASS_HEADER); //NOI18N
1291: }
1292:
1293: boolean[] buttonRequests = { paging.firstButton,
1294: paging.previousButton, paging.nextButton,
1295: paging.lastButton };
1296: String[] buttonLabels = { paging.firstButtonText,
1297: paging.previousButtonText, paging.nextButtonText,
1298: paging.lastButtonText };
1299: String[] buttonUrls = { paging.firstButtonUrl,
1300: paging.previousButtonUrl, paging.nextButtonUrl,
1301: paging.lastButtonUrl };
1302: String[] navButtonNames = { "FirstButton", "PreviousButton",
1303: "NextButton", "LastButton" }; //NOI18N
1304: String[] defaultButtonUrls = { DEFAULT_FIRST_URL,
1305: DEFAULT_PREVIOUS_URL, DEFAULT_NEXT_URL,
1306: DEFAULT_LAST_URL };
1307: String[] defaultButtonImgs = { DEFAULT_FIRST_IMG,
1308: DEFAULT_PREVIOUS_IMG, DEFAULT_NEXT_IMG,
1309: DEFAULT_LAST_IMG };
1310: String facetPrefix = facetStr.equals("header") ? "Header"
1311: : "Footer"; //NOI18N
1312:
1313: for (int i = 0; i < buttonRequests.length; i++) {
1314: if (buttonRequests[i]) {
1315: //create a button
1316: DesignBean btn = context.createBean(
1317: HtmlCommandButton.class.getName(), facet, null);
1318: btn.setInstanceName(tableBean.getInstanceName()
1319: + facetPrefix + navButtonNames[i]); //NOI18N
1320: btn.getProperty("immediate").setValue(Boolean.TRUE); //NOI18N
1321: if (BUTTON_TEXT.equals(paging.navigation)
1322: && buttonLabels[i] != null
1323: && buttonLabels[i].length() > 0) {
1324: if (isJsfELSyntax(buttonLabels[i])) {
1325: btn.getProperty("value").setValueSource(
1326: buttonLabels[i]); //NOI18N
1327: } else {
1328: btn.getProperty("value").setValue(
1329: buttonLabels[i]); //NOI18N
1330: }
1331: }
1332: if (BUTTON_IMAGE.equals(paging.navigation)
1333: && buttonUrls[i] != null
1334: && buttonUrls[i].length() > 0) {
1335: String urlToUse = buttonUrls[i];
1336: if (buttonUrls[i].equals(defaultButtonUrls[i])) {
1337: boolean resourceAlreadyInProject = false;
1338:
1339: //HACK? The designtime API should probably expose whether the resource is already in the project
1340: URL localFileUrl = context
1341: .resolveResource(buttonUrls[i]); // like file://C:/Documents and Settings/blah/blah/.../paging_first.png
1342: String localFileUrlStr = localFileUrl
1343: .toString();
1344: final String protocol = "file:/"; //NOI18N
1345: if (localFileUrlStr.startsWith(protocol)) {
1346: String localFilePath = localFileUrlStr
1347: .substring(protocol.length()); // like C:/Documents and Settings/blah/blah/.../paging_first.png
1348: //possibly with leading /
1349: localFilePath = localFilePath.replaceAll(
1350: "%20", " ");
1351: if (localFilePath.startsWith("/")
1352: && localFilePath.length() > 1) {
1353: localFilePath = localFilePath
1354: .substring(1, localFilePath
1355: .length()); //trim leading /
1356: }
1357: File localFile = new File(localFilePath);
1358: resourceAlreadyInProject = localFile
1359: .exists();
1360: }
1361:
1362: if (!resourceAlreadyInProject) {
1363: URL urlToDefaultImage = HtmlDataTableState.class
1364: .getResource(defaultButtonImgs[i]);
1365: try {
1366: urlToUse = context.addResource(
1367: urlToDefaultImage, true);
1368: } catch (IOException ioe) {
1369: ioe.printStackTrace();
1370: }
1371: }
1372: }
1373: if (isJsfELSyntax(urlToUse)) {
1374: btn.getProperty("image").setValueSource(
1375: urlToUse);
1376: } else {
1377: btn.getProperty("image").setValue(urlToUse);
1378: }
1379: }
1380:
1381: //get the btn's action event
1382: DesignEvent actionEvent = getActionEvent(btn);
1383:
1384: //set the handler name. a NullPointerException will be thrown if insync did not provide an action event.
1385: actionEvent.setHandlerName(tableBean.getInstanceName()
1386: + PAGING_HANDLER_SUFFIXES[i]); //like dataTable47_previousPageAction
1387:
1388: //set the handler source.
1389: String handlerMethodSource = "//not implemented\n"; //NOI18N
1390: switch (i) {
1391: case 0:
1392: handlerMethodSource = getFirstButtonHandlerSource();
1393: break;
1394: case 1:
1395: handlerMethodSource = getPreviousButtonHandlerSource();
1396: break;
1397: case 2:
1398: handlerMethodSource = getNextButtonHandlerSource();
1399: break;
1400: case 3:
1401: handlerMethodSource = getLastButtonHandlerSource();
1402: break;
1403: }
1404: //System.err.println("HtmlDataTableState.createNavPanel(" + facetStr + "): actionEvent.handlerMethodSource will be:\n" + handlerMethodSource + "!"); //NOI18N
1405: actionEvent.setHandlerMethodSource(handlerMethodSource);
1406: //System.err.println("HtmlDataTableState.createNavPanel(" + facetStr + "): actionEvent.handlerName:" + actionEvent.getHandlerName() + "!"); //NOI18N
1407: //System.err.println("HtmlDataTableState.createNavPanel(" + facetStr + "): actionEvent.handlerMethodSource:\n" + actionEvent.getHandlerMethodSource() + "!"); //NOI18N
1408: }
1409: }
1410: }
1411:
1412: private String getFirstButtonHandlerSource() {
1413: StringBuffer sb = new StringBuffer("\n"); //NOI18N
1414: sb.append(" " + tableBean.getInstanceName()
1415: + ".setFirst(0);\n"); //NOI18N
1416: sb.append(" return null;"); //NOI18N
1417: return sb.toString();
1418: }
1419:
1420: private String getPreviousButtonHandlerSource() {
1421: StringBuffer sb = new StringBuffer("\n"); //NOI18N
1422: String tbInstName = tableBean.getInstanceName();
1423: sb.append(" int first = " + tbInstName
1424: + ".getFirst() - " + tbInstName + //NOI18N
1425: ".getRows();\n"); //NOI18N
1426: sb.append(" if (first < 0) {\n"); //NOI18N
1427: sb.append(" first = 0;\n"); //NOI18N
1428: sb.append(" }\n"); //NOI18N
1429: sb.append(" " + tbInstName + ".setFirst(first);\n"); //NOI18N
1430: sb.append(" return null;"); //NOI18N
1431: return sb.toString();
1432: }
1433:
1434: private String getNextButtonHandlerSource() {
1435: StringBuffer sb = new StringBuffer("\n"); //NOI18N
1436: String tbInstName = tableBean.getInstanceName();
1437: sb.append(" int first = " + tbInstName
1438: + ".getFirst() + " + tbInstName + //NOI18N
1439: ".getRows();\n"); //NOI18N
1440: sb.append(" " + tbInstName + ".setRowIndex(first);\n"); //NOI18N
1441: sb.append(" if (" + tbInstName
1442: + ".isRowAvailable()) {\n"); //NOI18N
1443: sb.append(" " + tbInstName + ".setFirst(first);\n"); //NOI18N
1444: sb.append(" }\n"); //NOI18N
1445: sb.append(" return null;"); //NOI18N
1446: return sb.toString();
1447: }
1448:
1449: private String getLastButtonHandlerSource() {
1450: StringBuffer sb = new StringBuffer("\n"); //NOI18N
1451: String tbInstName = tableBean.getInstanceName();
1452: sb.append(" int first = " + tbInstName
1453: + ".getFirst();\n"); //NOI18N
1454: sb.append(" while (true) {\n"); //NOI18N
1455: sb.append(" " + tbInstName
1456: + ".setRowIndex(first + 1);\n"); //NOI18N
1457: sb.append(" if (" + tbInstName
1458: + ".isRowAvailable()) {\n"); //NOI18N
1459: sb.append(" first++;\n"); //NOI18N
1460: sb.append(" } else {\n"); //NOI18N
1461: sb.append(" break;\n"); //NOI18N
1462: sb.append(" }\n"); //NOI18N
1463: sb.append(" }\n"); //NOI18N
1464: sb.append(" " + tbInstName
1465: + ".setFirst(first - (first % " + tbInstName + //NOI18N
1466: ".getRows()));\n"); //NOI18N
1467: sb.append(" return null;"); //NOI18N
1468: return sb.toString();
1469: }
1470:
1471: public void dumpState(PrintStream out) {
1472: //out.println("datatable: " + instanceName); //NOI18N
1473: out.println(" sourceBean: " + sourceBean); //NOI18N
1474: out.println(" var: " + varName); //NOI18N
1475: ResultSetColumn[] rsca = rsinfo.getColumns();
1476: out.println(" columns: (" + rsca.length + " total)"); //NOI18N
1477: for (int i = 0; i < rsca.length; i++) {
1478: ResultSetColumn rsc = rsca[i];
1479: out.println(" column: [" + rsc.tableName + DOT
1480: + rsc.columnName + "]"); //NOI18N
1481: //out.println(" class: " + rsc.columnClassName); //NOI18N
1482: //out.println(" sqlType: " + rsc.columnSqlType + ": " + rsc.columnSqlTypeName); //NOI18N
1483: }
1484: out.println(" display:"); //NOI18N
1485: out.println(" rows: " + paging.rows); //NOI18N
1486: DisplayColumn[] dca = display.getColumns();
1487: out.println(" columns: (" + dca.length + " total)"); //NOI18N
1488: for (int i = 0; i < dca.length; i++) {
1489: DisplayColumn dc = dca[i];
1490: out.println(" column: " + dc.columnInstanceName); //NOI18N
1491: //out.println(" compInstanceName: " + dc.compInstanceName); //NOI18N
1492: out.println(" class: " + dc.compClassName); //NOI18N
1493: out.println(" valueRef: " + dc.compValueRef); //NOI18N
1494: //out.println(" converter: " + dc.compConverter); //NOI18N
1495: //out.println(" validator: " + dc.compValidator); //NOI18N
1496: out.println(" header: " + dc.headerText); //NOI18N
1497: //out.println(" headerLink: " + dc.headerLink); //NOI18N
1498: out.println(" footer: " + dc.footerText); //NOI18N
1499: out.println(" itemText: " + dc.itemText); //NOI18N
1500: }
1501: }
1502: }
|