Difference between revisions of "ADempiere Best Practices"
(→Coding Style) |
(Bringing rules from forums) |
||
Line 54: | Line 54: | ||
[http://svn.collab.net/repos/svn/trunk/doc/user/svn-best-practices.html SVN Best Practices] | [http://svn.collab.net/repos/svn/trunk/doc/user/svn-best-practices.html SVN Best Practices] | ||
+ | |||
+ | =Rules discussed in forums= | ||
+ | |||
+ | == Trackers must be descriptive == | ||
+ | |||
+ | http://sourceforge.net/forum/forum.php?thread_id=2681108&forum_id=610548 | ||
+ | |||
+ | == Don't drop not-added-by-you things == | ||
+ | |||
+ | http://sourceforge.net/forum/forum.php?thread_id=2667992&forum_id=610548 | ||
+ | |||
+ | == Always review collaterals == | ||
+ | |||
+ | http://sourceforge.net/forum/forum.php?thread_id=2668000&forum_id=610548 | ||
+ | |||
+ | == not to commit a change if you only have solved it for one database == | ||
+ | |||
+ | http://sourceforge.net/forum/forum.php?thread_id=2668000&forum_id=610548 | ||
+ | |||
+ | == Just one version of ModelGenerator == | ||
+ | |||
+ | http://sourceforge.net/forum/forum.php?thread_id=2663645&forum_id=610548 | ||
+ | |||
==Suggestions & Questions of Commit Policy== | ==Suggestions & Questions of Commit Policy== | ||
Line 193: | Line 216: | ||
*Solicit help from others if you cannot document well. Or just start a stub and allow others to expand it. | *Solicit help from others if you cannot document well. Or just start a stub and allow others to expand it. | ||
*Intentionally hiding information may get your contribution categorised as proprietary and not fit for admission into trunk. | *Intentionally hiding information may get your contribution categorised as proprietary and not fit for admission into trunk. | ||
+ | |||
[[Category:Community]] | [[Category:Community]] | ||
[[Category:Documentation]] | [[Category:Documentation]] |
Revision as of 20:41, 18 December 2008
Contents
Overview
DISCLAIMER: Target of this document is developers who want to help us fixing and completing ADempiere's manufacturing functionality (libero).
Goal
Team
Teo Sarca Arhipac : Libero stabilization
Cristina Ghita Arhipac : Libero stabilization
Development Methodology
Sugesstion & Questions Development Methodology
Eclipse Process Framework Project (EPF) Demo
SVN Commit Policy
FIRST DRAFT PLEASE ADD TO AS YOU SEE FIT... The following guidelines describe the best practice when committing code in the Adempiere repository.
- All commits should be atomic: that is they are the complete code patch that addresses a Bug Report [BR] or Feature Request [FR] in sourceforge. If the contribution is unusually large it may be committed in small parts but then commit should be distinct functional parts.
- Commit Early in YOUR day: Only commit if you are around to support or even revert in case of a problems.
- All commits related to BR or FR: with consensus on the functional and technical change how the change will be accomplished (in general).
- Update before commit: Do an SVN update and ensure all still compiles locally before you commit.
- Reference the BR/FR in the commit comments: include the full url to the sourceforge BR/FR, but also include a short, but descriptive, comment that does not require the reader to go to the BR/FR in sourceforge unless they require details.
- Example:
- [ 2354040 ] Implementation Replication Mode, Type, Event
- http://sourceforge.net/tracker/index.php?func=detail&aid=2354040&group_id=176962&atid=879335
- Enhance replication to allow export and import of documents and then execute the document status action.
- Syncronise & Build: after committing sync again with the repository and confirm all still builds without errors.
- On successful commit Update the BR/FR: include the SVN revision reference and set the status & resolution fields as appropriate.
Reference
Rules discussed in forums
Trackers must be descriptive
http://sourceforge.net/forum/forum.php?thread_id=2681108&forum_id=610548
Don't drop not-added-by-you things
http://sourceforge.net/forum/forum.php?thread_id=2667992&forum_id=610548
Always review collaterals
http://sourceforge.net/forum/forum.php?thread_id=2668000&forum_id=610548
not to commit a change if you only have solved it for one database
http://sourceforge.net/forum/forum.php?thread_id=2668000&forum_id=610548
Just one version of ModelGenerator
http://sourceforge.net/forum/forum.php?thread_id=2663645&forum_id=610548
Suggestions & Questions of Commit Policy
Coding Standards
Sugesstion & Questions Coding Standards
Coding Style
See Eclipse Code Formatter Profile .
1. Use DB.getSQLValueEx instead of DB.getSQLValue. It's much better to throw an exception if error. If you use DB.getSQLValue, will not make the difference between "did not find any value" and was an exceptional SQL.
2. Do not use the conversion from Integer to int, Double to double and so on, because from java5 is doing autoboxing.
3. Allways use bracelets {}.
4. Don't use transaction names if is not necessary. Better put null.
Known issues:
- At present eclipse formatter is not supporting fluent interfaces (see eclipse bug #196001)
How to use Adempiere Query class?
How to return only ONE persistent object?
StringBuilder whereClause = new StringBuilder(); whereClause.append("AD_Client_ID=?"); // #1 whereClause.append(" AND AD_Org_ID=?"); // #2 whereClause.append(" AND C_AcctSchema_ID=?"); // #3 whereClause.append(" AND Account_ID=?"); // #4 MAccount existingAccount = new Query(ctx, I_C_ValidCombination.Table_Name, whereClause.toString(), null) .setParameters(new Object[]{AD_Client_ID, AD_Org_ID, C_AcctSchema_ID, Account_ID}) .first();
If you know that your query should return ONLY one result, then you can assert this, and use firstOnly method instead of first method:
MAccount existingAccount = new Query(ctx, I_C_ValidCombination.Table_Name, whereClause, null) .setParameters(new Object[]{AD_Client_ID, AD_Org_ID, C_AcctSchema_ID, Account_ID}) .'''firstOnly'''();
How to return ARRAY of objects?
public static MAchievement[] getOfMeasure (Properties ctx, int PA_Measure_ID) { final String whereClause = COLUMNNAME_PA_Measure_ID+"=?"; List<MAchievement> list = new Query(ctx, I_PA_Achievement.Table_Name, whereClause, null) .setParameters(new Object[]{PA_Measure_ID}) .setOrderBy(COLUMNNAME_SeqNo+", "+COLUMNNAME_DateDoc) .list(); return list.toArray(new MAchievement[list.size()]); }
How to return ARRAY of objects and process elements?
public static MAchievement[] getOfMeasure (Properties ctx, int PA_Measure_ID) { String whereClause = COLUMNNAME_PA_Measure_ID+"=? AND "+COLUMNNAME_IsAchieved+"=?"; List<MAchievement> list = new Query(ctx, MAchievement.Table_Name, whereClause, null) .setParameters(new Object[]{PA_Measure_ID, true}) .setOrderBy(COLUMNNAME_SeqNo+", "+COLUMNNAME_DateDoc) .list(); for(MAchievement achievement : list) { s_log.fine(" - " + achievement); // do some processing here } return list.toArray(new MAchievement[list.size()]); }
How to return one member of an object?
public static int getWindow_ID(String windowName) { int retValue = 0; String whereClause = COLUMNNAME_Name+"=?"; MWindow win = new Query(Env.getCtx(), MWindow.Table_Name, whereClause, null) .setParameters(new Object[]{windowName}) .first(); return = win.getAD_Window_ID(); }
How to pass Timestamp parameter?
Timestamp dateAcct = ...; String trxName = ...; StringBuilder whereClause = new StringBuilder(); whereClause.append("C_CashBook_ID=?"); // #1 whereClause.append(" AND TRUNC(StatementDate)=?"); // #2 whereClause.append(" AND Processed=?"); // #3 MCash retValue = new Query(ctx, MCash.Table_Name, whereClause.toString(), trxName) .setParameters(new Object[]{C_CashBook_ID, TimeUtil.getDay(dateAcct), true}) .first() ;
How to use Query class with complex where clause: EXISTS?
StringBuilder whereClause = new StringBuilder(); whereClause.append("C_Cash.AD_Org_ID=?"); // #1 whereClause.append(" AND TRUNC(C_Cash.StatementDate)=?"); // #2 whereClause.append(" AND C_Cash.Processed='N'"); whereClause.append(" AND EXISTS (SELECT * FROM C_CashBook cb"); whereClause.append(" WHERE C_Cash.C_CashBook_ID=cb.C_CashBook_ID AND cb.AD_Org_ID=C_Cash.AD_Org_ID"); whereClause.append(" AND cb.C_Currency_ID=?)"); // #3 MCash retValue = new Query(ctx, MCash.Table_Name, whereClause, trxName) .setParameters(new Object[]{AD_Org_ID,TimeUtil.getDay(dateAcct),C_Currency_ID}) .first() ;
References
Sugesstion & Questions Coding Style
When on a single thread class, StringBuilder should be used for String concatenation. If the class is not single threaded, then, StringBuffer should be used for String concatenation.
Testing Policy
- Submit your changes to local testing or a peer review before committing unless you are approved by 1st level committer
- Publish your test results
Test Units
- ... (test unit contributions needed)
Documentation Policy
- Document your sourcecode changes in this wiki under appropriate topic.
- Solicit help from others if you cannot document well. Or just start a stub and allow others to expand it.
- Intentionally hiding information may get your contribution categorised as proprietary and not fit for admission into trunk.