KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > compiere > model > PO


1 /******************************************************************************
2  * The contents of this file are subject to the Compiere License Version 1.1
3  * ("License"); You may not use this file except in compliance with the License
4  * You may obtain a copy of the License at http://www.compiere.org/license.html
5  * Software distributed under the License is distributed on an "AS IS" basis,
6  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
7  * the specific language governing rights and limitations under the License.
8  * The Original Code is Compiere ERP & CRM Business Solution
9  * The Initial Developer of the Original Code is Jorg Janke and ComPiere, Inc.
10  * Portions created by Jorg Janke are Copyright (C) 1999-2001 Jorg Janke, parts
11  * created by ComPiere are Copyright (C) ComPiere, Inc.; All Rights Reserved.
12  * Contributor(s): ______________________________________.
13  *****************************************************************************/

14 package org.compiere.model;
15
16 import java.util.*;
17 import java.sql.*;
18 import javax.sql.*;
19 import java.math.*;
20 import java.io.*;
21
22 import oracle.sql.*;
23 import oracle.jdbc.*;
24
25 import org.compiere.util.*;
26
27 /**
28  * Persistent Object.
29  * Superclass for actual implementations
30  *
31  * @author Jorg Janke
32  * @version $Id: PO.java,v 1.29 2003/11/06 07:09:09 jjanke Exp $
33  */

34 public abstract class PO implements Serializable, Comparator
35 {
36     /**
37      * Create New Persisent Object
38      * @param ctx context
39      */

40     public PO (Properties ctx)
41     {
42         this (ctx, 0, null);
43     } // PO
44

45     /**
46      * Create & Load existing Persistent Object
47      * @para ID The unique ID of the object
48      * @param ctx context
49      * @param ID Record_ID or 0 for new
50      */

51     public PO (Properties ctx, int ID)
52     {
53         this (ctx, ID, null);
54     } // PO
55

56     /**
57      * Create & Load existing Persistent Object.
58      * <pre>
59      * You load
60      * - an existing single key record with new PO (ctx, Record_ID)
61      * or new PO (ctx, rs)
62      * - a new single key record with new PO (ctx, 0)
63      * - an existing multi key record with new PO (ctx, rs)
64      * - a new multi key record with new PO (ctx, null)
65      * The ID for new single key records is created automatically,
66      * you need to set the IDs for multi-key records explicitly.
67      * </pre>
68      * @param ctx context
69      * @param rs optional - load from current result set position (no navigation, not closed)
70      */

71     public PO (Properties ctx, ResultSet rs)
72     {
73         this (ctx, 0, rs);
74     } // PO
75

76     /**
77      * Create & Load existing Persistent Object.
78      * <pre>
79      * You load
80      * - an existing single key record with new PO (ctx, Record_ID)
81      * or new PO (ctx, rs)
82      * - a new single key record with new PO (ctx, 0)
83      * - an existing multi key record with new PO (ctx, rs)
84      * - a new multi key record with new PO (ctx, null)
85      * The ID for new single key records is created automatically,
86      * you need to set the IDs for multi-key records explicitly.
87      * </pre>
88      * @param ctx context
89      * @param ID the ID if 0, the record defaults are applied - ignored if re exists
90      * @param rs optional - load from current result set position (no navigation, not closed)
91      */

92     public PO (Properties ctx, int ID, ResultSet rs)
93     {
94         p_ctx = ctx;
95         p_info = initPO(ctx);
96         //
97
int size = p_info.getColumnCount();
98         m_oldValues = new Object JavaDoc[size];
99         m_newValues = new Object JavaDoc[size];
100         if (rs != null)
101             load(rs);
102         else
103             load(ID);
104     } // PO
105

106     /**
107      * Create New PO by Copying existing (key not copied).
108      * @param ctx context
109      * @param source souce object
110      * @param AD_Client_ID client
111      * @param AD_Org_ID org
112      */

113     public PO (Properties ctx, PO source, int AD_Client_ID, int AD_Org_ID)
114     {
115         this (ctx, 0, null); // create new
116
//
117
if (source != null)
118             copyValues (source, this);
119         setAD_Client_ID(AD_Client_ID);
120         setAD_Org_ID(AD_Org_ID);
121     } // PO
122

123
124     /** Logger */
125     protected Logger log = Logger.getCLogger (getClass());
126     private static Logger s_log = Logger.getCLogger (PO.class);
127
128     /** Context */
129     protected Properties p_ctx;
130     /** Model Info */
131     protected POInfo p_info = null;
132
133     /** Original Values */
134     private Object JavaDoc[] m_oldValues = null;
135     /** New Valies */
136     private Object JavaDoc[] m_newValues = null;
137
138     /** Record_IDs */
139     private Object JavaDoc[] m_IDs = new Object JavaDoc[] {new Integer JavaDoc(0)};
140     /** Key Columns */
141     private String JavaDoc[] m_KeyColumns = null;
142     /** Create New for Multi Key */
143     private boolean m_createNew = false;
144
145     /** NULL value */
146     private static final Object JavaDoc NULL = new Object JavaDoc();
147
148     /**
149      * Initialize and return PO_Info
150      * @param ctx context
151      * @return POInfo
152      */

153     abstract protected POInfo initPO (Properties ctx);
154
155     /**
156      * String representation
157      * @return String representation
158      */

159     public String JavaDoc toString()
160     {
161         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("PO[")
162             .append(getWhereClause(true)).append("]");
163         return sb.toString();
164     } // toString
165

166     /**
167      * Equals
168      * @param cmp comperator
169      * @return true if ID the same
170      */

171     public boolean equals (Object JavaDoc cmp)
172     {
173         if (cmp == null)
174             return false;
175         if (cmp.getClass().equals(this.getClass()))
176             return ((PO)cmp).getID() == getID();
177         return equals(cmp);
178     } // equals
179

180     /**
181      * Compare
182      * @param o1 Object 1
183      * @param o2 Object 2
184      * @return -1 if o1 < o2
185      */

186     public int compare (Object JavaDoc o1, Object JavaDoc o2)
187     {
188         if (o1 == null)
189             return -1;
190         else if (o2 == null)
191             return 1;
192         if (!(o1 instanceof PO))
193             throw new ClassCastException JavaDoc ("Not PO -1- " + o1);
194         if (!(o2 instanceof PO))
195             throw new ClassCastException JavaDoc ("Not PO -2- " + o2);
196         // same class
197
if (o1.getClass().equals(o2.getClass()))
198         {
199             int index = getColumnIndex("DocumentNo");
200             if (index == -1)
201                 index = getColumnIndex("Value");
202             if (index == -1)
203                 index = getColumnIndex("Name");
204             if (index == -1)
205                 index = getColumnIndex("Description");
206             if (index != -1)
207             {
208                 PO po1 = (PO)o1;
209                 Object JavaDoc comp1 = po1.getValue(index);
210                 PO po2 = (PO)o2;
211                 Object JavaDoc comp2 = po2.getValue(index);
212                 if (comp1 == null)
213                     return -1;
214                 else if (comp2 == null)
215                     return 1;
216                 return comp1.toString().compareTo(comp2.toString());
217             }
218         }
219         return o1.toString().compareTo(o2.toString());
220     } // compare
221

222     /**
223      * Get TableName
224      * @return table name
225      */

226     protected String JavaDoc getTableName()
227     {
228         return p_info.getTableName();
229     } // getTableName
230

231     /**
232      * Return Single Key Record ID
233      * @return ID or 0
234      */

235     public int getID()
236     {
237         Object JavaDoc oo = m_IDs[0];
238         if (oo != null && oo instanceof Integer JavaDoc)
239             return ((Integer JavaDoc)oo).intValue();
240         return 0;
241     } // getID
242

243     /**
244      * Get Context
245      * @return context
246      */

247     public Properties getCtx()
248     {
249         return p_ctx;
250     } // getCtx
251

252
253     /**
254      * Get Value
255      * @param index index
256      * @return value
257      */

258     protected Object JavaDoc getValue (int index)
259     {
260         if (index < 0 || index >= getColumnCount())
261         {
262             log.error("getValue - Index invalid - " + index);
263             return null;
264         }
265         if (m_newValues[index] != null)
266         {
267             if (m_newValues[index].equals(NULL))
268                 return null;
269             return m_newValues[index];
270         }
271         return m_oldValues[index];
272     } // getValue
273

274     /**
275      * Get Value
276      * @param index index
277      * @return int value or 0
278      */

279     protected int getValueAsInt (int index)
280     {
281         Object JavaDoc value = getValue(index);
282         if (value == null)
283             return 0;
284         if (value instanceof Integer JavaDoc)
285             return ((Integer JavaDoc)value).intValue();
286         try
287         {
288             return Integer.parseInt(value.toString());
289         }
290         catch (NumberFormatException JavaDoc ex)
291         {
292             log.warn("getValueAsInt - " + p_info.getColumnName(index) + " - " + ex.getMessage());
293             return 0;
294         }
295     } // getValue
296

297     /**
298      * Get Value
299      * @param columnName column name
300      * @return calue
301      */

302     protected Object JavaDoc getValue (String JavaDoc columnName)
303     {
304         int index = getColumnIndex(columnName);
305         if (index < 0)
306         {
307             log.error("getValue - Column not found - " + columnName);
308             return null;
309         }
310         return getValue (index);
311     } // getValue
312

313     /**
314      * Set Value if updateable and correct class.
315      * (and to NULL if not mandatory)
316      * @param index index
317      * @param value value
318      * @return true if value set
319      */

320     protected final boolean setValue (int index, Object JavaDoc value)
321     {
322         if (index < 0 || index >= getColumnCount())
323         {
324             log.error("setValue - Index invalid - " + index);
325             return false;
326         }
327         String JavaDoc ColumnName = p_info.getColumnName(index);
328         String JavaDoc colInfo = " - " + ColumnName;
329         if (p_info.isColumnUpdateable(index))
330         {
331             if (value == null)
332             {
333                 if (p_info.isColumnMandatory(index))
334                 {
335                     log.error("setValue - Cannot set mandatory column to null " + colInfo);
336                 // Trace.printStack();
337
return false;
338                 }
339                 m_newValues[index] = NULL; // correct
340
if (Log.isTraceLevel(Log.l6_Database))
341                     log.debug("setValue - " + ColumnName + " = null");
342             }
343             else
344             {
345                 // matching class or generic object
346
if (value.getClass().equals(p_info.getColumnClass(index)) || p_info.getColumnClass(index) == Object JavaDoc.class)
347                     m_newValues[index] = value; // correct
348
// Integer can be set as BigDecimal (VNumber returns always BigDecimal)
349
else if (value.getClass() == BigDecimal.class && p_info.getColumnClass(index) == Integer JavaDoc.class)
350                     m_newValues[index] = new Integer JavaDoc (((BigDecimal)value).intValue());
351                 else
352                 {
353                     log.error("setValue - " + ColumnName
354                         + " - Class invalid: " + value.getClass().toString()
355                         + ", Should be " + p_info.getColumnClass(index).toString() + colInfo);
356                     return false;
357                 }
358                 // Validate (Min/Max)
359
String JavaDoc error = p_info.validate(index, value);
360                 if (error != null)
361                 {
362                     log.error("setValue - " + ColumnName + "=" + value + " - " + error);
363                     return false;
364                 }
365                 //
366
if (Log.isTraceLevel(8))
367                     log.debug("setValue - " + ColumnName + " = " + value);
368                 // length for String
369
if (p_info.getColumnClass(index) == String JavaDoc.class)
370                 {
371                     String JavaDoc stringValue = value.toString();
372                     int length = p_info.getFieldLength(index);
373                     if (stringValue.length() > length)
374                     {
375                         log.warn("setValue - " + ColumnName + " - Value too long - truncated to length=" + length);
376                         m_newValues[index] = stringValue.substring(0,length-1);
377                     }
378                 }
379             }
380         }
381         else
382         {
383             colInfo += " - NewValue=" + value + " - OldValue=" + getValue(index);
384             log.error("setValue - Column not updateable" + colInfo);
385             return false;
386         }
387         setKeys (ColumnName, value);
388         return true;
389     } // setValue
390

391     /**
392      * Set Value
393      * @param ColumnName column name
394      * @param value value
395      * @return true if value set
396      */

397     protected final boolean setValue (String JavaDoc ColumnName, Object JavaDoc value)
398     {
399         int index = getColumnIndex(ColumnName);
400         if (index < 0)
401         {
402             log.error("setValue - Column not found - " + ColumnName);
403             return false;
404         }
405         return setValue (index, value);
406     } // setValue
407

408     /**
409      * Set Value w/o check (update, r/o, ..).
410      * Required for key and parent values
411      * @param ColumnName column name
412      * @param value value
413      * @return true if value set
414      */

415     protected final boolean setValueNoCheck (String JavaDoc ColumnName, Object JavaDoc value)
416     {
417         int index = getColumnIndex(ColumnName);
418         if (index < 0)
419         {
420             log.error("setValueNoCheck - Column not found - " + ColumnName);
421             return false;
422         }
423         m_newValues[index] = value; // write direct
424
if (Log.isTraceLevel(Log.l6_Database))
425             log.debug("setValueNoCheck - " + ColumnName + " = " + value);
426         setKeys (ColumnName, value);
427         return true;
428     } // setValueNoCheck
429

430     /**
431      * Set (numeric) Key Value
432      * @param ColumnName column name
433      * @param value value
434      */

435     private void setKeys (String JavaDoc ColumnName, Object JavaDoc value)
436     {
437         // Update if KeyColumn
438
for (int i = 0; i < m_IDs.length; i++)
439         {
440             if (ColumnName.equals (m_KeyColumns[i]))
441             {
442                 m_IDs[i] = value;
443             }
444         } // for all key columns
445
} // setKeys
446

447     /*************************************************************************/
448
449     /**
450      * Get Column Count
451      * @return column count
452      */

453     protected int getColumnCount()
454     {
455         return p_info.getColumnCount();
456     } // getColumnCount
457

458     /**
459      * Get Column Name
460      * @param index index
461      * @return ColumnName
462      */

463     protected String JavaDoc getColumnName (int index)
464     {
465         return p_info.getColumnName (index);
466     } // getColumnName
467

468     /**
469      * Get Column Label
470      * @param index index
471      * @return Column Label
472      */

473     protected String JavaDoc getColumnLabel (int index)
474     {
475         return p_info.getColumnLabel (index);
476     } // getColumnLabel
477

478     /**
479      * Get Column Description
480      * @param index index
481      * @return column description
482      */

483     protected String JavaDoc getColumnDescription (int index)
484     {
485         return p_info.getColumnDescription (index);
486     } // getColumnDescription
487

488     /**
489      * Is Column Mandatory
490      * @param index index
491      * @return true if column mandatory
492      */

493     protected boolean isColumnMandatory (int index)
494     {
495         return p_info.isColumnMandatory(index);
496     } // isColumnNandatory
497

498     /**
499      * Is Column Updateable
500      * @param index index
501      * @return true if column updateable
502      */

503     protected boolean isColumnUpdateable (int index)
504     {
505         return p_info.isColumnUpdateable(index);
506     } // isColumnUpdateable
507

508     /**
509      * Set Column Updateable
510      * @param index index
511      * @param updateable column updateable
512      */

513     protected void setColumnUpdateable (int index, boolean updateable)
514     {
515         p_info.setColumnUpdateable(index, updateable);
516     } // setColumnUpdateable
517

518     /**
519      * Set all columns updateable
520      * @param updateable updateable
521      */

522     protected void setUpdateable (boolean updateable)
523     {
524         p_info.setUpdateable (updateable);
525     } // setUpdateable
526

527     /**
528      * Get Column Index
529      * @param columnName column name
530      * @return index of column
531      */

532     protected int getColumnIndex (String JavaDoc columnName)
533     {
534         return p_info.getColumnIndex(columnName);
535     } // getColumnIndex
536

537     /**
538      * Get Lookup
539      * @param index index
540      * @return Lookup or null
541      */

542     protected Lookup getColumnLookup(int index)
543     {
544         return p_info.getColumnLookup(index);
545     } // getColumnLookup
546

547
548     /**
549      * Copy old values of From to new values of To.
550      * Does not copy Keys
551      * @param from old, existing & unchanged PO
552      * @param to new, not saved PO
553      * @param AD_Client_ID client
554      * @param AD_Org_ID org
555      */

556     protected static void copyValues (PO from, PO to, int AD_Client_ID, int AD_Org_ID)
557     {
558         copyValues (from, to);
559         to.setAD_Client_ID(AD_Client_ID);
560         to.setAD_Org_ID(AD_Org_ID);
561     } // copyValues
562

563     /**
564      * Copy old values of From to new values of To.
565      * Does not copy Keys and AD_Client_ID/AD_Org_ID
566      * @param from old, existing & unchanged PO
567      * @param to new, not saved PO
568      */

569     protected static void copyValues (PO from, PO to)
570     {
571         s_log.debug("copyValues - From ID=" + from.getID() + " - To ID=" + to.getID());
572         if (from.getClass() != to.getClass())
573             throw new IllegalArgumentException JavaDoc("PO.copyValues - To class=" + to.getClass() + " NOT From=" + from.getClass());
574         //
575
for (int i = 0; i < from.m_oldValues.length; i++)
576         {
577             String JavaDoc colName = from.p_info.getColumnName(i);
578             // Ignore Standard Values
579
if (colName.startsWith("Created") || colName.startsWith("Updated")
580             // || colName.equals(from.getTableName() + "_ID") // KeyColumn
581
|| from.p_info.isColumnKey(i)
582                 || colName.equals("IsActive")
583                 || colName.equals("AD_Client_ID") || colName.equals("AD_Org_ID"))
584                 ; // ignore
585
else
586                 to.m_newValues[i] = from.m_oldValues[i];
587         }
588     } // copy
589

590     /*************************************************************************/
591
592     /**
593      * Load record with ID
594      * @param ID ID
595      */

596     protected void load (int ID)
597     {
598         if (Log.isTraceLevel(10))
599             log.debug("load - ID=" + ID);
600         if (ID > 0)
601         {
602             m_IDs = new Object JavaDoc[] {new Integer JavaDoc(ID)};
603             m_KeyColumns = new String JavaDoc[] {getTableName() + "_ID"};
604             load();
605         }
606         else // new
607
{
608             loadDefaults();
609             m_createNew = true;
610             setKeyInfo(); // sets m_IDs
611
}
612     } // load
613

614
615     /**
616      * (re)Load record with m_ID[*]
617      */

618     protected void load ()
619     {
620         StringBuffer JavaDoc sql = new StringBuffer JavaDoc("SELECT ");
621         int size = getColumnCount();
622         for (int i = 0; i < size; i++)
623         {
624             if (i != 0)
625                 sql.append(",");
626             sql.append(getColumnName(i));
627         }
628         sql.append(" FROM ").append(getTableName())
629             .append(" WHERE ")
630             .append(getWhereClause(false));
631         //
632
int index = -1;
633         if (Log.isTraceLevel(10))
634             log.debug("load - " + getWhereClause(true));
635         try
636         {
637             PreparedStatement pstmt = DB.prepareStatement(sql.toString());
638             for (int i = 0; i < m_IDs.length; i++)
639             {
640                 Object JavaDoc oo = m_IDs[i];
641                 if (oo instanceof Integer JavaDoc)
642                     pstmt.setInt(i+1, ((Integer JavaDoc)m_IDs[i]).intValue());
643                 else
644                     pstmt.setString(i+1, m_IDs[i].toString());
645             }
646             ResultSet rs = pstmt.executeQuery();
647             if (rs.next())
648             {
649                 // load column values
650
for (index = 0; index < size; index++)
651                 {
652                     Class JavaDoc clazz = p_info.getColumnClass(index);
653                     int dt = p_info.getColumnDisplayType(index);
654                     //
655
if (clazz == Integer JavaDoc.class)
656                         m_oldValues[index] = new Integer JavaDoc(rs.getInt(index+1));
657                     else if (clazz == BigDecimal.class)
658                         m_oldValues[index] = rs.getBigDecimal(index+1);
659                     else if (clazz == Boolean JavaDoc.class)
660                         m_oldValues[index] = new Boolean JavaDoc ("Y".equals(rs.getString(index+1)));
661                     else if (clazz == Timestamp.class)
662                         m_oldValues[index] = rs.getTimestamp(index+1);
663                     else if (dt == DisplayType.TextLong)
664                         m_oldValues[index] = getLOB (rs.getObject(index+1));
665                     else if (clazz == String JavaDoc.class)
666                         m_oldValues[index] = rs.getString(index+1);
667                     else
668                         m_oldValues[index] = loadSpecial(rs, index);
669                     if (rs.wasNull() && m_oldValues[index] != null)
670                         m_oldValues[index] = null;
671                     //
672
if (Log.isTraceLevel(10))
673                         log.debug(String.valueOf(index) + ": " + p_info.getColumnName(index) + "(" + p_info.getColumnClass(index) + ") = " + m_oldValues[index]);
674                 }
675             }
676             else
677             {
678                 log.error("load - NO Data found for " + getWhereClause(true));
679                 m_IDs = new Object JavaDoc[] {new Integer JavaDoc(0)};
680             }
681             rs.close();
682             pstmt.close();
683             m_createNew = false;
684             // reset new values
685
m_newValues = new Object JavaDoc[size];
686         }
687         catch (SQLException e)
688         {
689             log.error ("load - " + getWhereClause(true)
690                 + ", Index=" + index + ", Column=" + getColumnName(index)
691                 + ", " + p_info.toString(index)
692                 + ", SQL=" + sql.toString(), e);
693         }
694     } // load
695

696
697     /**
698      * Load from the current position of a ResultSet
699      * @param rs result set
700      */

701     protected void load (ResultSet rs)
702     {
703         int size = getColumnCount();
704         int index = 0;
705         if (Log.isTraceLevel(10))
706             log.debug("load(rs)");
707         try
708         {
709             // load column values
710
for (index = 0; index < size; index++)
711             {
712                 String JavaDoc columnName = p_info.getColumnName(index);
713                 Class JavaDoc clazz = p_info.getColumnClass(index);
714                 int dt = p_info.getColumnDisplayType(index);
715                 //
716
if (clazz == Integer JavaDoc.class)
717                     m_oldValues[index] = new Integer JavaDoc(rs.getInt(columnName));
718                 else if (clazz == BigDecimal.class)
719                     m_oldValues[index] = rs.getBigDecimal(columnName);
720                 else if (clazz == Boolean JavaDoc.class)
721                     m_oldValues[index] = new Boolean JavaDoc ("Y".equals(rs.getString(columnName)));
722                 else if (clazz == Timestamp.class)
723                     m_oldValues[index] = rs.getTimestamp(columnName);
724                 else if (dt == DisplayType.TextLong)
725                     m_oldValues[index] = getLOB (rs.getObject(columnName));
726                 else if (clazz == String JavaDoc.class)
727                     m_oldValues[index] = rs.getString(columnName);
728                 else
729                     m_oldValues[index] = loadSpecial(rs, index);
730                 if (rs.wasNull() && m_oldValues[index] != null)
731                     m_oldValues[index] = null;
732                 //
733
if (Log.isTraceLevel(10))
734                     log.debug(String.valueOf(index) + ": " + p_info.getColumnName(index)
735                         + "(" + p_info.getColumnClass(index) + ") = " + m_oldValues[index]);
736             }
737             m_createNew = false;
738         }
739         catch (SQLException e)
740         {
741             log.error ("load(rs) - " + String.valueOf(index) + ": " + p_info.getColumnName(index)
742                 + "(" + p_info.getColumnClass(index) + ")", e);
743
744         }
745         setKeyInfo();
746     } // load
747

748
749     /**
750      * Load Special data (images, ..).
751      * To be extended by sub-classes
752      * @param rs result set
753      * @param index zero based index
754      * @return value value
755      * @throws SQLException
756      */

757     protected Object JavaDoc loadSpecial (ResultSet rs, int index) throws SQLException
758     {
759         if (Log.isTraceLevel(Log.l4_Data))
760             log.debug("loadSpecial - " + p_info.getColumnName(index));
761         return null;
762     } // loadSpecial
763

764     /**
765      * Load Defaults
766      */

767     protected void loadDefaults()
768     {
769         setStandardDefaults();
770         //
771
/** @todo defaults from Field */
772     // MField.getDefault(p_info.getDefaultLogic(i));
773
} // loadDefaults
774

775     /**
776      * Set Default values.
777      * Client, Org, Created/Updated, *By, IsActive
778      */

779     protected void setStandardDefaults()
780     {
781         int size = getColumnCount();
782         for (int i = 0; i < size; i++)
783         {
784             String JavaDoc colName = p_info.getColumnName(i);
785             // Set Standard Values
786
if (colName.endsWith("tedBy"))
787                 m_newValues[i] = new Integer JavaDoc (Env.getContextAsInt(p_ctx, "#AD_User_ID"));
788             else if (colName.equals("Created") || colName.equals("Updated"))
789                 m_newValues[i] = new Timestamp (System.currentTimeMillis());
790             else if (colName.equals(getTableName() + "_ID")) // KeyColumn
791
m_newValues[i] = new Integer JavaDoc(0);
792             else if (colName.equals("IsActive"))
793                 m_newValues[i] = new Boolean JavaDoc(true);
794             else if (colName.equals("AD_Client_ID"))
795                 m_newValues[i] = new Integer JavaDoc(Env.getContextAsInt(p_ctx, "#AD_Client_ID"));
796             else if (colName.equals("AD_Org_ID"))
797                 m_newValues[i] = new Integer JavaDoc(Env.getContextAsInt(p_ctx, "#AD_Org_ID"));
798         }
799     } // setDefaults
800

801     /**
802      * Set Key Info (IDs and KeyColumns)
803      */

804     private void setKeyInfo()
805     {
806         // Search for Primary Key
807
for (int i = 0; i < p_info.getColumnCount(); i++)
808         {
809             if (p_info.isColumnKey(i) && p_info.getColumnName(i).endsWith("_ID"))
810             {
811                 String JavaDoc ColumnName = p_info.getColumnName(i);
812                 m_KeyColumns = new String JavaDoc[] {ColumnName};
813                 Integer JavaDoc ii = (Integer JavaDoc)getValue(i);
814                 if (ii == null)
815                     m_IDs = new Object JavaDoc[] {new Integer JavaDoc(0)};
816                 else
817                     m_IDs = new Object JavaDoc[] {ii};
818                 if (Log.isTraceLevel(10))
819                     log.debug("PO.setKeyInfo (PK) - " + ColumnName + "=" + ii);
820                 return;
821             }
822         } // primary key search
823

824         // Search for Parents
825
ArrayList columnNames = new ArrayList();
826         for (int i = 0; i < p_info.getColumnCount(); i++)
827         {
828             if (p_info.isColumnParent(i))
829                 columnNames.add(p_info.getColumnName(i));
830         }
831         // Set FKs
832
int size = columnNames.size();
833         if (size == 0)
834             throw new IllegalStateException JavaDoc("PO.setKeyInfo - no PK nor FK - " + p_info.getTableName());
835         m_IDs = new Object JavaDoc[size];
836         m_KeyColumns = new String JavaDoc[size];
837         for (int i = 0; i < size; i++)
838         {
839             m_KeyColumns[i] = (String JavaDoc)columnNames.get(i);
840             if (m_KeyColumns[i].endsWith("_ID"))
841             {
842                 Integer JavaDoc ii = null;
843                 try
844                 {
845                     ii = (Integer JavaDoc)getValue(m_KeyColumns[i]);
846                 }
847                 catch (Exception JavaDoc e)
848                 {
849                     log.error("setKeyInfo", e);
850                 }
851                 if (ii != null)
852                     m_IDs[i] = ii;
853             }
854             else
855                 m_IDs[i] = getValue(m_KeyColumns[i]);
856             if (Log.isTraceLevel(10))
857                 log.debug("setKeyInfo (FK) " + m_KeyColumns[i] + "=" + m_IDs[i]);
858         }
859     } // setKeyInfo
860

861     /*************************************************************************/
862
863     /**
864      * Are all mandatory Fields filled (i.e. can we save)?.
865      * Stops at first null mandatory field
866      * @return true if all mandatory fields are ok
867      */

868     protected boolean isMandatoryOK()
869     {
870         int size = getColumnCount();
871         for (int i = 0; i < size; i++)
872         {
873             if (p_info.isColumnMandatory(i))
874             {
875                 if (getValue(i) == null || getValue(i).equals(NULL))
876                 {
877                     log.info("isMandatoryOK " + p_info.getColumnName(i));
878                     return false;
879                 }
880             }
881         }
882         return true;
883     } // isMandatoryOK
884

885     /************************************************************************/
886
887     /**
888      * Set AD_Client
889      * @param AD_Client_ID client
890      */

891     final protected void setAD_Client_ID (int AD_Client_ID)
892     {
893         setValueNoCheck ("AD_Client_ID", new Integer JavaDoc(AD_Client_ID));
894     } // setAD_Client_ID
895

896     /**
897      * Get AD_Client
898      * @return AD_Client_ID
899      */

900     public final int getAD_Client_ID()
901     {
902         return ((Integer JavaDoc)getValue("AD_Client_ID")).intValue();
903     } // getAD_Client_ID
904

905     /**
906      * Set AD_Org
907      * @param AD_Org_ID org
908      */

909     final protected void setAD_Org_ID (int AD_Org_ID)
910     {
911         setValueNoCheck ("AD_Org_ID", new Integer JavaDoc(AD_Org_ID));
912     } // setAD_Org_ID
913

914     /**
915      * Get AD_Org
916      * @return AD_Org_ID
917      */

918     public final int getAD_Org_ID()
919     {
920         return ((Integer JavaDoc)getValue("AD_Org_ID")).intValue();
921     } // getAD_Org_ID
922

923     /**
924      * Overwrite Client Org if different
925      * @param AD_Client_ID client
926      * @param AD_Org_ID org
927      */

928     protected void setClientOrg (int AD_Client_ID, int AD_Org_ID)
929     {
930         if (AD_Client_ID != getAD_Client_ID())
931             setAD_Client_ID(AD_Client_ID);
932         if (AD_Org_ID != getAD_Org_ID())
933             setAD_Org_ID(AD_Org_ID);
934     } // setClientOrg
935

936     /**
937      * Set Active
938      * @param active active
939      */

940     public final void setIsActive (boolean active)
941     {
942         setValue("IsActive", new Boolean JavaDoc(active));
943     } // setActive
944

945     /**
946      * Is Active
947      * @return is active
948      */

949     public final boolean isActive()
950     {
951         Boolean JavaDoc bb = (Boolean JavaDoc)getValue("IsActive");
952         if (bb != null)
953             return bb.booleanValue();
954         return false;
955     } // isActive
956

957     /**
958      * Get Created
959      * @return created
960      */

961     final public Timestamp getCreated()
962     {
963         return (Timestamp)getValue("Created");
964     } // getCreated
965

966     /**
967      * Get Updated
968      * @return updated
969      */

970     final public Timestamp getUpdated()
971     {
972         return (Timestamp)getValue("Updated");
973     } // getUpdated
974

975     /**
976      * Get CreatedBy
977      * @return AD_User_ID
978      */

979     final public int getCreatedBy()
980     {
981         Integer JavaDoc ii = (Integer JavaDoc)getValue("CreatedBy");
982         if (ii == null)
983             return 0;
984         return ii.intValue();
985     } // getCreateddBy
986

987     /**
988      * Get UpdatedBy
989      * @return AD_User_ID
990      */

991     final public int getUpdatedBy()
992     {
993         Integer JavaDoc ii = (Integer JavaDoc)getValue("UpdatedBy");
994         if (ii == null)
995             return 0;
996         return ii.intValue();
997     } // getUpdatedBy
998

999     /**
1000     * Set UpdatedBy
1001     * @param AD_User_ID user
1002     */

1003    final protected void setUpdatedBy (int AD_User_ID)
1004    {
1005        setValueNoCheck ("UpdatedBy", new Integer JavaDoc(AD_User_ID));
1006    } // setAD_User_ID
1007

1008    /************************************************************************/
1009
1010    /**
1011     * Update Value or create new record
1012     * @return true if saved
1013     */

1014    public boolean save()
1015    {
1016        // New
1017
if (!m_createNew && m_IDs[0].equals(new Integer JavaDoc(0))) // first key value = 0
1018
m_createNew = true;
1019        if (m_createNew)
1020            return saveNew();
1021        return saveUpdate();
1022    }
1023
1024    /**
1025     * Update Record directly
1026     * @return true if updated
1027     */

1028    protected boolean saveUpdate()
1029    {
1030        String JavaDoc where = getWhereClause(true);
1031        log.info("saveUpdate - " + p_info.getTableName() + where);
1032        //
1033
boolean changes = false;
1034        StringBuffer JavaDoc sql = new StringBuffer JavaDoc ("UPDATE ");
1035        sql.append(getTableName()).append( " SET ");
1036        boolean updated = false;
1037        boolean updatedBy = false;
1038        resetLOB();
1039
1040        int size = getColumnCount();
1041        for (int i = 0; i < size; i++)
1042        {
1043            // we have a change
1044
if (m_newValues[i] != null)
1045            {
1046                Object JavaDoc value = m_newValues[i];
1047                Class JavaDoc c = p_info.getColumnClass(i);
1048                int dt = p_info.getColumnDisplayType(i);
1049                //
1050
if (dt == DisplayType.TextLong)
1051                    saveLOBprepare (value, i, dt);
1052
1053                if (changes)
1054                    sql.append(", ");
1055                changes = true;
1056                sql.append(p_info.getColumnName(i)).append("=");
1057                
1058                // values
1059
if (value == NULL)
1060                    sql.append("NULL");
1061                else if (c == Integer JavaDoc.class || c == BigDecimal.class)
1062                    sql.append(m_newValues[i]);
1063                else if (c == Boolean JavaDoc.class)
1064                {
1065                    value = "'N'";
1066                    if (((Boolean JavaDoc)m_newValues[i]).booleanValue())
1067                        value = "'Y'";
1068                    sql.append(value);
1069                }
1070                else if (c == Timestamp.class)
1071                    sql.append(DB.TO_DATE((Timestamp)m_newValues[i],p_info.getColumnDisplayType(i) == DisplayType.Date));
1072                else
1073                    sql.append(DB.TO_STRING(m_newValues[i].toString()));
1074                // updated/by
1075
if (p_info.getColumnName(i).equals("UpdatedBy"))
1076                    updatedBy = true;
1077                else if (p_info.getColumnName(i).equals("Updated"))
1078                    updated = true;
1079            } // changed field
1080
} // for all fields
1081
//
1082
if (changes)
1083        {
1084            if (!updated) // Updated not explicitly set
1085
{
1086                Timestamp now = new Timestamp(System.currentTimeMillis());
1087                setValueNoCheck("Updated", now);
1088                sql.append(",Updated=").append(DB.TO_DATE(now, false));
1089            }
1090            if (!updatedBy) // UpdatedBy not explicitly set
1091
{
1092                int AD_User_ID = Env.getContextAsInt(p_ctx, "#AD_User_ID");
1093                setValueNoCheck("UpdatedBy", new Integer JavaDoc(AD_User_ID));
1094                sql.append(",UpdatedBy=").append(AD_User_ID);
1095            }
1096            sql.append(" WHERE ").append(where);
1097            /** @todo optimistic locking goes here */
1098        }
1099
1100        if (changes)
1101        {
1102            int no = DB.executeUpdate(sql.toString());
1103            if (no == 1)
1104                saveLOB(false);
1105            return saveComplete (false, no == 1);
1106        }
1107        // nothing changed, so OK
1108
return saveComplete (false, true);
1109    } // saveUpdate
1110

1111    /**
1112     * Create New Record
1113     * @return true if new record inserted
1114     */

1115    private boolean saveNew()
1116    {
1117        // Set ID for single key - Multi-Key values need explicitly be set previously
1118
if (m_IDs.length == 1 && !m_KeyColumns[0].equals("AD_Language"))
1119        {
1120            m_IDs[0] = new Integer JavaDoc(DB.getKeyNextNo(getAD_Client_ID(), getTableName()));
1121            setValueNoCheck(m_KeyColumns[0], m_IDs[0]);
1122        }
1123        log.debug("saveNew - " + p_info.getTableName() + " - " + getWhereClause(true));
1124        // DocumentNo
1125
String JavaDoc DN = "DocumentNo";
1126        int index = p_info.getColumnIndex(DN);
1127        if (index != -1)
1128        {
1129            Object JavaDoc value = getValue(index);
1130            if (value == null || value.toString().length() == 0)
1131            {
1132                int AD_Client_ID = getAD_Client_ID();
1133                int dt = p_info.getColumnIndex("C_DocType_ID");
1134                if (dt != -1)
1135                    value = DB.getDocumentNo(AD_Client_ID, getValueAsInt(dt));
1136                else
1137                    value = DB.getDocumentNo(AD_Client_ID, "N", getTableName());
1138                setValueNoCheck(DN, value);
1139            }
1140        }
1141        resetLOB();
1142
1143        // SQL
1144
StringBuffer JavaDoc sqlInsert = new StringBuffer JavaDoc("INSERT INTO ");
1145        sqlInsert.append(getTableName()).append(" (");
1146        StringBuffer JavaDoc sql = new StringBuffer JavaDoc(") VALUES (");
1147        int size = getColumnCount();
1148        for (int i = 0; i < size; i++)
1149        {
1150            Object JavaDoc value = getValue(i);
1151            int dt = p_info.getColumnDisplayType(index);
1152            if (dt == DisplayType.TextLong)
1153                saveLOBprepare (value, i, dt);
1154            
1155            // ** add column **
1156
if (i > 0)
1157            {
1158                sqlInsert.append(",");
1159                sql.append(",");
1160            }
1161            sqlInsert.append(p_info.getColumnName(i));
1162            //
1163
// Based on class of definition, not class of value
1164
Class JavaDoc c = p_info.getColumnClass(i);
1165            try
1166            {
1167                if (c == Object JavaDoc.class) // may have need to deal with null values differently
1168
sql.append (saveNewSpecial (value, i));
1169                else if (value == null || value.equals (NULL))
1170                    sql.append ("NULL");
1171                else if (c == Integer JavaDoc.class)
1172                    sql.append (((Integer JavaDoc)value).intValue ());
1173                else if (c == BigDecimal.class)
1174                    sql.append (((BigDecimal)value).toString ());
1175                else if (c == Boolean JavaDoc.class)
1176                    sql.append (((Boolean JavaDoc)value).booleanValue () ? "'Y'"
1177                      : "'N'");
1178                else if (c == Timestamp.class)
1179                    sql.append (DB.TO_DATE ((Timestamp)value,
1180                      p_info.getColumnDisplayType (i) == DisplayType.Date));
1181                else if (c == String JavaDoc.class)
1182                    sql.append (DB.TO_STRING ((String JavaDoc)value));
1183                else if (dt == DisplayType.TextLong)
1184                    sql.append("empty_clob()");
1185                else
1186                    sql.append (saveNewSpecial (value, i));
1187            }
1188            catch (Exception JavaDoc e)
1189            {
1190                log.error("PO.saveNew - " + p_info.toString(i) + " - " + value, e);
1191                throw new RuntimeException JavaDoc (e);
1192            }
1193        }
1194        sqlInsert.append(sql)
1195            .append(")");
1196        //
1197
int no = DB.executeUpdate(sqlInsert.toString());
1198        if (no == 1)
1199        {
1200            saveLOB(true);
1201            load(); // re-read Info
1202
}
1203        else
1204            log.error("PO.saveNew - Not inserted - " + sql.toString());
1205        //
1206
return saveComplete(true, no == 1);
1207    } // createNew
1208

1209    /**
1210     * Create Single/Multi Key Where Clause
1211     * @param withValues if true uses actual values otherwise ?
1212     * @return where clause
1213     */

1214    private String JavaDoc getWhereClause (boolean withValues)
1215    {
1216        StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
1217        for (int i = 0; i < m_IDs.length; i++)
1218        {
1219            if (i != 0)
1220                sb.append(" AND ");
1221            sb.append(m_KeyColumns[i]).append("=");
1222            if (withValues)
1223                sb.append(m_IDs[i]);
1224            else
1225                sb.append("?");
1226        }
1227        return sb.toString();
1228    } // getWhereClause
1229

1230
1231    /**
1232     * Save Special Data.
1233     * To be extended by sub-classes
1234     * @param value value
1235     * @param index index
1236     * @return SQL code for INSERT VALUES clause
1237     */

1238    protected String JavaDoc saveNewSpecial (Object JavaDoc value, int index)
1239    {
1240        String JavaDoc colName = p_info.getColumnName(index);
1241        String JavaDoc colClass = p_info.getColumnClass(index).toString();
1242        String JavaDoc colValue = value == null ? "null" : value.getClass().toString();
1243        int dt = p_info.getColumnDisplayType(index);
1244
1245        log.error("PO.saveNewSpecial - Unknown class for column " + colName
1246            + " (" + colClass + ") - Value=" + colValue);
1247            
1248        if (value == null)
1249            return "NULL";
1250        return value.toString();
1251    } // saveNewSpecial
1252

1253    /**
1254     * Save new or update complete.
1255     * To be extended by sub-classes
1256     * @param newRecord new record
1257     * @param success success
1258     * @return true if save complete (if not overwritten true)
1259     */

1260    protected boolean saveComplete (boolean newRecord, boolean success)
1261    {
1262        log.debug("saveComplete - Success=" + success);
1263        m_createNew = false;
1264        return success;
1265    } // saveComplete
1266

1267
1268    /*************************************************************************/
1269
1270    /**
1271     * Delete Current Record
1272     * @return true if deleted
1273     */

1274    public boolean delete()
1275    {
1276        if (m_createNew || m_IDs[0].equals(new Integer JavaDoc(0))) // new
1277
return true;
1278
1279        StringBuffer JavaDoc sql = new StringBuffer JavaDoc ("DELETE ")
1280            .append(getTableName())
1281            .append(" WHERE ")
1282            .append(getWhereClause(true));
1283        //
1284
int no = DB.executeUpdate(sql.toString());
1285        if (no == 0)
1286            m_IDs[0] = new Integer JavaDoc(0);
1287        return no == 1;
1288    } // delete
1289

1290    /*************************************************************************/
1291
1292    /**
1293     * Dump Record
1294     */

1295    public void dump ()
1296    {
1297        if (Log.isTraceLevel(8))
1298        {
1299            log.debug (getWhereClause (true));
1300            for (int i = 0; i < getColumnCount (); i++)
1301                dump (i);
1302        }
1303    } // dump
1304

1305    /**
1306     * Dump column
1307     * @param index index
1308     */

1309    public void dump (int index)
1310    {
1311        StringBuffer JavaDoc sb = new StringBuffer JavaDoc(" ").append(index);
1312        if (index < 0 || index >= getColumnCount())
1313        {
1314            log.debug(sb.append(": invalid").toString());
1315            return;
1316        }
1317        sb.append(": ").append(getColumnName(index))
1318            .append(" = ").append(m_oldValues[index])
1319            .append(" (").append(m_newValues[index]).append(")");
1320        log.debug(sb.toString());
1321    } // dump
1322

1323    /*************************************************************************/
1324
1325    /**
1326     * Get All IDs of Table
1327     * @param TableName table name (key column with _ID)
1328     * @param WhereClause optional where clause
1329     * @return array of IDs
1330     */

1331    public static int[] getAllIDs (String JavaDoc TableName, String JavaDoc WhereClause)
1332    {
1333        ArrayList list = new ArrayList();
1334        StringBuffer JavaDoc sql = new StringBuffer JavaDoc("SELECT ");
1335        sql.append(TableName).append("_ID FROM ").append(TableName);
1336        if (WhereClause != null && WhereClause.length() > 0)
1337            sql.append(" WHERE ").append(WhereClause);
1338        try
1339        {
1340            PreparedStatement pstmt = DB.prepareStatement(sql.toString());
1341            ResultSet rs = pstmt.executeQuery();
1342            while (rs.next())
1343                list.add(new Integer JavaDoc(rs.getInt(1)));
1344            rs.close();
1345            pstmt.close();
1346        }
1347        catch (SQLException e)
1348        {
1349            s_log.error("getAllIDs\nSQL=" + sql.toString(), e);
1350        }
1351        // Convert to array
1352
int[] retValue = new int[list.size()];
1353        for (int i = 0; i < retValue.length; i++)
1354            retValue[i] = ((Integer JavaDoc)list.get(i)).intValue();
1355        return retValue;
1356    } // getAllIDs
1357

1358    /*************************************************************************/
1359    
1360    /**
1361     * Load LOB
1362     * @param value LOB
1363     */

1364    private Object JavaDoc getLOB (Object JavaDoc value)
1365    {
1366        log.debug("getLOB - " + value);
1367        if (value == null)
1368            return null;
1369        //
1370
String JavaDoc retValue = null;
1371        try
1372        {
1373            if (value instanceof Clob)
1374            {
1375                Clob lob = (Clob)value;
1376                long length = lob.length();
1377                retValue = lob.getSubString(1, (int)length);
1378            }
1379        }
1380        catch (Exception JavaDoc e)
1381        {
1382            log.error("getLOB", e);
1383        }
1384        return retValue;
1385    } // getLOB
1386

1387
1388    private ArrayList m_lobInfo = null;
1389
1390    private void resetLOB()
1391    {
1392        m_lobInfo = null;
1393    }
1394    private void saveLOBprepare (Object JavaDoc value, int index, int displayType)
1395    {
1396        log.debug("saveLOBprepare - " + value);
1397        LOBInfoVO info = new LOBInfoVO();
1398        info.value = value;
1399        info.index = index;
1400        info.displayType = displayType;
1401        if (m_lobInfo == null)
1402            m_lobInfo = new ArrayList();
1403        m_lobInfo.add(info);
1404    }
1405    
1406    private void saveLOB (boolean newRecord)
1407    {
1408        if (m_lobInfo == null)
1409            return;
1410        for (int i = 0; i < m_lobInfo.size(); i++)
1411        {
1412            LOBInfoVO info = (LOBInfoVO)m_lobInfo.get(i);
1413            log.debug("saveLOB - " + info.value);
1414        // newLOB (info); // always create new
1415
//
1416
StringBuffer JavaDoc sql = new StringBuffer JavaDoc ("SELECT ");
1417            sql.append(getColumnName(info.index))
1418                .append(" FROM ").append(getTableName())
1419                .append(" WHERE ").append(getWhereClause(true))
1420                .append(" FOR UPDATE");
1421            log.debug("saveLOB - " + sql);
1422            Connection con = null;
1423            PreparedStatement pstmt = null;
1424            try
1425            {
1426                con = DB.createConnection(false, Connection.TRANSACTION_SERIALIZABLE);
1427                pstmt = con.prepareStatement(sql.toString(), ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
1428                OracleResultSet rs = (OracleResultSet)pstmt.executeQuery();
1429                if (rs.next())
1430                {
1431                    CLOB lob = rs.getCLOB(1);
1432                    Writer writer = lob.getCharacterOutputStream();
1433                    writer.write((String JavaDoc)info.value);
1434                    writer.flush();
1435                    writer.close();
1436                }
1437                rs.close();
1438                pstmt.close();
1439                pstmt = null;
1440                con.close();
1441                con = null;
1442            }
1443            catch (Exception JavaDoc e)
1444            {
1445                log.error("saveLOB", e);
1446            }
1447            try
1448            {
1449                if (pstmt != null)
1450                    pstmt.close();
1451                pstmt = null;
1452                if (con != null)
1453                    con.close();
1454                con = null;
1455            }
1456            catch (Exception JavaDoc e)
1457            {
1458                pstmt = null;
1459                con = null;
1460            }
1461        } // for all LOBs
1462
resetLOB();
1463    } // saveLOB
1464

1465    
1466    private boolean newLOB (LOBInfoVO info)
1467    {
1468        StringBuffer JavaDoc sql = new StringBuffer JavaDoc ("UPDATE ");
1469        sql.append(getTableName())
1470            .append(" SET ").append(getColumnName(info.index)).append("=");
1471        if (info.displayType == DisplayType.TextLong)
1472            sql.append("empty_clob()");
1473        else
1474            sql.append("empty_blob()");
1475        sql.append(" WHERE ").append(getWhereClause(true));
1476        int no = DB.executeUpdate(sql.toString());
1477        log.debug("newLOB - " + no + " - " + sql.toString());
1478        return no == 1;
1479    } // newLOB
1480

1481    class LOBInfoVO
1482    {
1483        public Object JavaDoc value;
1484        public int index;
1485        public int displayType;
1486    } // LOBInfoVO
1487

1488
1489    /*************************************************************************/
1490
1491    /**
1492     * Test
1493     * @param args args
1494     */

1495    public static void main (String JavaDoc[] args)
1496    {
1497        BigDecimal min = new BigDecimal (1);
1498
1499    } // main
1500

1501} // PO
1502
Popular Tags