OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Compare Revisions

Regard whitespace Rev 64 → Rev 65

/trunk/OpenConcerto/lib/jOpenDocument-1.3b1.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/lib/jOpenDocument-1.3b2.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/lib/jOpenDocument-1.3b2.jar
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/OpenConcerto/Configuration/main.properties
1,5 → 1,5
#OpenConcerto
#Mon Feb 27 11:24:30 CET 2012
#Mon Jul 23 19:49:42 CEST 2012
systemRoot=OpenConcerto
server.ip=192.168.1.10\:5432
base.root=Common
/trunk/OpenConcerto/Configuration/Logo.png
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Logo.png
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/OpenConcerto/Configuration/Template/Default/local_Devis.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/local_Devis.ods
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/OpenConcerto/Configuration/Template/Default/local_Balance.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/Configuration/Template/Default/local_Balance.ods
New file
Property changes:
Added: svn:mime-type
+application/octet-stream
\ No newline at end of property
/trunk/OpenConcerto/Configuration/Template/Default/VenteFacture.xml
44,7 → 44,7
<element location="C13" type="fill">
<field base="Societe" table="SAISIE_VENTE_FACTURE" name="DATE"/>
</element>
 
<element type="invoice_paid_amount" location="L65"/>
<element location="B16" type="fill">
<field base="Societe" table="SAISIE_VENTE_FACTURE" name="ID_COMMERCIAL">
<field base="Societe" table="COMMERCIAL" name="PRENOM" type="Initiale" suffix="."/>
/trunk/OpenConcerto/Configuration/Template/Default/local_Balance.odsp
New file
0,0 → 1,9
<odsp>
<spliteveryrow>
<sheet number="0">71</sheet>
</spliteveryrow>
<offset x="40" y ="20"/>
<resize percent="85"/>
 
 
</odsp>
/trunk/OpenConcerto/Configuration/Template/Default/local_Devis.xml
New file
0,0 → 1,123
<?xml version="1.0" encoding="UTF-8" ?>
 
<contentDocument>
 
<element location="B1" type="fill">
<field base="Common" table="SOCIETE_COMMON" name="TYPE"/>
<field base="Common" table="SOCIETE_COMMON" name="NOM"/>
</element>
 
<element location="B2" type="fill">
<field base="Common" table="SOCIETE_COMMON" name="ID_ADRESSE_COMMON">
<field base="Common" table="ADRESSE_COMMON" name="RUE"/>
</field>
</element>
 
<element location="B3" type="fill">
<field base="Common" table="SOCIETE_COMMON" name="ID_ADRESSE_COMMON">
<field base="Common" table="ADRESSE_COMMON" name="VILLE" type="villeCP"/>
<field base="Common" table="ADRESSE_COMMON" name="VILLE" type="ville"/>
</field>
</element>
<element location="B7" type="replace" replacePattern="_">
<field base="Common" table="SOCIETE_COMMON" name="NUM_NII"/>
</element>
<element location="B8" type="replace" replacePattern="_">
<field base="Common" table="SOCIETE_COMMON" name="NUM_TEL"/>
</element>
<element location="B9" type="replace" replacePattern="_">
<field base="Common" table="SOCIETE_COMMON" name="NUM_FAX"/>
</element>
<element location="B10" type="replace" replacePattern="_">
<field base="Common" table="SOCIETE_COMMON" name="MAIL"/>
</element>
<element location="B16" type="fill">
<field base="Societe" table="DEVIS" name="ID_COMMERCIAL">
<field base="Societe" table="COMMERCIAL" name="PRENOM" type="Initiale" suffix="."/>
<field base="Societe" table="COMMERCIAL" name="NOM"/>
</field>
</element>
 
<element location="B13" type="fill">
<field base="Societe" table="DEVIS" name="NUMERO"/>
</element>
<element location="C13" type="fill">
<field base="Societe" table="DEVIS" name="DATE"/>
</element>
<element location="C16" type="fill">
<field base="Societe" table="DEVIS" name="OBJET"/>
</element>
<element location="I10" type="fill">
<field base="Societe" table="DEVIS" name="ID_CLIENT">
<field base="Societe" table="CLIENT" name="FORME_JURIDIQUE"/>
<field base="Societe" table="CLIENT" name="NOM"/>
</field>
</element>
<element location="I11" type="fill">
<field base="Societe" table="DEVIS" name="ID_CLIENT">
<field base="Societe" table="CLIENT" name="ID_ADRESSE">
<field base="Societe" table="ADRESSE" name="RUE"/>
</field>
</field>
</element>
<element location="I13" type="fill">
<field base="Societe" table="DEVIS" name="ID_CLIENT">
<field base="Societe" table="CLIENT" name="ID_ADRESSE">
<field base="Societe" table="ADRESSE" name="VILLE" type="villeCP"/>
<field base="Societe" table="ADRESSE" name="VILLE" type="ville"/>
</field>
</field>
</element>
 
 
<element location="L63" type="fill">
<field base="Societe" table="DEVIS" name="T_HT" type="devise"/>
</element>
<element location="L64" type="fill">
<field base="Societe" table="DEVIS" name="T_TVA" type="devise"/>
</element>
<element location="L65" type="fill">
<field base="Societe" table="DEVIS" name="T_TTC" type="devise"/>
</element>
 
<table endPageLine="65" firstLine="21" endLine="60" lastColumn="L" base="Societe" table="DEVIS_ELEMENT" blankLineBeforeStyle="Titre 1">
<element location="B" type="fill">
<field base="Societe" table="DEVIS_ELEMENT" name="NOM"/>
</element>
<element location="I" type="fill">
<field base="Societe" table="DEVIS_ELEMENT" name="PV_HT" type="devise" valuesExpected="0"/>
</element>
<element location="J" type="fill">
<field base="Societe" table="DEVIS_ELEMENT" name="QTE" conditionField="PV_HT" conditionExpValue="0"/>
</element>
 
<element location="K" type="fill">
<field base="Societe" table="DEVIS_ELEMENT" name="ID_TAXE" conditionField="PV_HT" conditionExpValue="0">
<field base="Societe" table="TAXE" name="TAUX" op="/" number="100.0" />
</field>
</element>
<element location="L" type="fill">
<field base="Societe" table="DEVIS_ELEMENT" name="T_PV_HT" type="devise" valuesExpected="0"/>
</element>
</table>
</contentDocument>
/trunk/OpenConcerto/Configuration/Template/Default/local_Devis.odsp
New file
0,0 → 1,12
<odsp>
 
<spliteveryrow>
<sheet number="0">65</sheet>
 
</spliteveryrow>
+<offset x="40" y ="20"/>
+<resize percent="85"/>
+
+</odsp>
\ No newline at end of file
/trunk/OpenConcerto/Configuration/Template/Default/Devis.ods
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
/trunk/OpenConcerto/src/org/postgresql/jdbc2/AbstractJdbc2DatabaseMetaData.java
New file
0,0 → 1,4273
/*-------------------------------------------------------------------------
*
* Copyright (c) 2004-2008, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgjdbc/org/postgresql/jdbc2/AbstractJdbc2DatabaseMetaData.java,v 1.57 2010/08/10 19:46:13 jurka Exp $
*
*-------------------------------------------------------------------------
*/
package org.postgresql.jdbc2;
 
import java.sql.*;
import java.util.*;
import org.postgresql.core.*;
import org.postgresql.util.PSQLException;
import org.postgresql.util.PSQLState;
import org.postgresql.Driver;
import org.postgresql.util.GT;
 
public abstract class AbstractJdbc2DatabaseMetaData
{
 
public AbstractJdbc2DatabaseMetaData(AbstractJdbc2Connection conn)
{
this.connection = conn;
}
 
 
private static final String keywords = "abort,acl,add,aggregate,append,archive," +
"arch_store,backward,binary,boolean,change,cluster," +
"copy,database,delimiter,delimiters,do,extend," +
"explain,forward,heavy,index,inherits,isnull," +
"light,listen,load,merge,nothing,notify," +
"notnull,oids,purge,rename,replace,retrieve," +
"returns,rule,recipe,setof,stdin,stdout,store," +
"vacuum,verbose,version";
 
protected final AbstractJdbc2Connection connection; // The connection association
 
private int NAMEDATALEN = 0; // length for name datatype
private int INDEX_MAX_KEYS = 0; // maximum number of keys in an index.
 
protected int getMaxIndexKeys() throws SQLException {
if (INDEX_MAX_KEYS == 0)
{
String sql;
if (connection.haveMinimumServerVersion("8.0")) {
sql = "SELECT setting FROM pg_catalog.pg_settings WHERE name='max_index_keys'";
} else {
String from;
if (connection.haveMinimumServerVersion("7.3"))
{
from = "pg_catalog.pg_namespace n, pg_catalog.pg_type t1, pg_catalog.pg_type t2 WHERE t1.typnamespace=n.oid AND n.nspname='pg_catalog' AND ";
}
else
{
from = "pg_type t1, pg_type t2 WHERE ";
}
sql = "SELECT t1.typlen/t2.typlen FROM " + from + " t1.typelem=t2.oid AND t1.typname='oidvector'";
}
ResultSet rs = connection.createStatement().executeQuery(sql);
if (!rs.next())
{
throw new PSQLException(GT.tr("Unable to determine a value for MaxIndexKeys due to missing system catalog data."), PSQLState.UNEXPECTED_ERROR);
}
INDEX_MAX_KEYS = rs.getInt(1);
rs.close();
}
return INDEX_MAX_KEYS;
}
 
protected int getMaxNameLength() throws SQLException {
if (NAMEDATALEN == 0)
{
String sql;
if (connection.haveMinimumServerVersion("7.3"))
{
sql = "SELECT t.typlen FROM pg_catalog.pg_type t, pg_catalog.pg_namespace n WHERE t.typnamespace=n.oid AND t.typname='name' AND n.nspname='pg_catalog'";
}
else
{
sql = "SELECT typlen FROM pg_type WHERE typname='name'";
}
ResultSet rs = connection.createStatement().executeQuery(sql);
if (!rs.next())
{
throw new PSQLException(GT.tr("Unable to find name datatype in the system catalogs."), PSQLState.UNEXPECTED_ERROR);
}
NAMEDATALEN = rs.getInt("typlen");
rs.close();
}
return NAMEDATALEN - 1;
}
 
 
/*
* Can all the procedures returned by getProcedures be called
* by the current user?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean allProceduresAreCallable() throws SQLException
{
return true; // For now...
}
 
/*
* Can all the tables returned by getTable be SELECTed by
* the current user?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean allTablesAreSelectable() throws SQLException
{
return true; // For now...
}
 
/*
* What is the URL for this database?
*
* @return the url or null if it cannott be generated
* @exception SQLException if a database access error occurs
*/
public String getURL() throws SQLException
{
return connection.getURL();
}
 
/*
* What is our user name as known to the database?
*
* @return our database user name
* @exception SQLException if a database access error occurs
*/
public String getUserName() throws SQLException
{
return connection.getUserName();
}
 
/*
* Is the database in read-only mode?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean isReadOnly() throws SQLException
{
return connection.isReadOnly();
}
 
/*
* Are NULL values sorted high?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean nullsAreSortedHigh() throws SQLException
{
return connection.haveMinimumServerVersion("7.2");
}
 
/*
* Are NULL values sorted low?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean nullsAreSortedLow() throws SQLException
{
return false;
}
 
/*
* Are NULL values sorted at the start regardless of sort order?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean nullsAreSortedAtStart() throws SQLException
{
return false;
}
 
/*
* Are NULL values sorted at the end regardless of sort order?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean nullsAreSortedAtEnd() throws SQLException
{
return !connection.haveMinimumServerVersion("7.2");
}
 
/*
* What is the name of this database product - we hope that it is
* PostgreSQL, so we return that explicitly.
*
* @return the database product name
* @exception SQLException if a database access error occurs
*/
public String getDatabaseProductName() throws SQLException
{
return "PostgreSQL";
}
 
/*
* What is the version of this database product.
*
* @return the database version
* @exception SQLException if a database access error occurs
*/
public String getDatabaseProductVersion() throws SQLException
{
return connection.getDBVersionNumber();
}
 
/*
* What is the name of this JDBC driver? If we don't know this
* we are doing something wrong!
*
* @return the JDBC driver name
* @exception SQLException why?
*/
public String getDriverName() throws SQLException
{
return "PostgreSQL Native Driver";
}
 
/*
* What is the version string of this JDBC driver? Again, this is
* static.
*
* @return the JDBC driver name.
* @exception SQLException why?
*/
public String getDriverVersion() throws SQLException
{
return Driver.getVersion();
}
 
/*
* What is this JDBC driver's major version number?
*
* @return the JDBC driver major version
*/
public int getDriverMajorVersion()
{
return Driver.MAJORVERSION;
}
 
/*
* What is this JDBC driver's minor version number?
*
* @return the JDBC driver minor version
*/
public int getDriverMinorVersion()
{
return Driver.MINORVERSION;
}
 
/*
* Does the database store tables in a local file? No - it
* stores them in a file on the server.
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean usesLocalFiles() throws SQLException
{
return false;
}
 
/*
* Does the database use a file for each table? Well, not really,
* since it doesnt use local files.
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean usesLocalFilePerTable() throws SQLException
{
return false;
}
 
/*
* Does the database treat mixed case unquoted SQL identifiers
* as case sensitive and as a result store them in mixed case?
* A JDBC-Compliant driver will always return false.
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsMixedCaseIdentifiers() throws SQLException
{
return false;
}
 
/*
* Does the database treat mixed case unquoted SQL identifiers as
* case insensitive and store them in upper case?
*
* @return true if so
*/
public boolean storesUpperCaseIdentifiers() throws SQLException
{
return false;
}
 
/*
* Does the database treat mixed case unquoted SQL identifiers as
* case insensitive and store them in lower case?
*
* @return true if so
*/
public boolean storesLowerCaseIdentifiers() throws SQLException
{
return true;
}
 
/*
* Does the database treat mixed case unquoted SQL identifiers as
* case insensitive and store them in mixed case?
*
* @return true if so
*/
public boolean storesMixedCaseIdentifiers() throws SQLException
{
return false;
}
 
/*
* Does the database treat mixed case quoted SQL identifiers as
* case sensitive and as a result store them in mixed case? A
* JDBC compliant driver will always return true.
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException
{
return true;
}
 
/*
* Does the database treat mixed case quoted SQL identifiers as
* case insensitive and store them in upper case?
*
* @return true if so
*/
public boolean storesUpperCaseQuotedIdentifiers() throws SQLException
{
return false;
}
 
/*
* Does the database treat mixed case quoted SQL identifiers as case
* insensitive and store them in lower case?
*
* @return true if so
*/
public boolean storesLowerCaseQuotedIdentifiers() throws SQLException
{
return false;
}
 
/*
* Does the database treat mixed case quoted SQL identifiers as case
* insensitive and store them in mixed case?
*
* @return true if so
*/
public boolean storesMixedCaseQuotedIdentifiers() throws SQLException
{
return false;
}
 
/*
* What is the string used to quote SQL identifiers? This returns
* a space if identifier quoting isn't supported. A JDBC Compliant
* driver will always use a double quote character.
*
* @return the quoting string
* @exception SQLException if a database access error occurs
*/
public String getIdentifierQuoteString() throws SQLException
{
return "\"";
}
 
/*
* Get a comma separated list of all a database's SQL keywords that
* are NOT also SQL92 keywords.
*
* <p>Within PostgreSQL, the keywords are found in
* src/backend/parser/keywords.c
*
* <p>For SQL Keywords, I took the list provided at
* <a href="http://web.dementia.org/~shadow/sql/sql3bnf.sep93.txt">
* http://web.dementia.org/~shadow/sql/sql3bnf.sep93.txt</a>
* which is for SQL3, not SQL-92, but it is close enough for
* this purpose.
*
* @return a comma separated list of keywords we use
* @exception SQLException if a database access error occurs
*/
public String getSQLKeywords() throws SQLException
{
return keywords;
}
 
/**
* get supported escaped numeric functions
* @return a comma separated list of function names
*/
public String getNumericFunctions() throws SQLException
{
return EscapedFunctions.ABS+','+EscapedFunctions.ACOS+
','+EscapedFunctions.ASIN+','+EscapedFunctions.ATAN+
','+EscapedFunctions.ATAN2+','+EscapedFunctions.CEILING+
','+EscapedFunctions.COS+','+EscapedFunctions.COT+
','+EscapedFunctions.DEGREES+','+EscapedFunctions.EXP+
','+EscapedFunctions.FLOOR+','+EscapedFunctions.LOG+
','+EscapedFunctions.LOG10+','+EscapedFunctions.MOD+
','+EscapedFunctions.PI+','+EscapedFunctions.POWER+
','+EscapedFunctions.RADIANS+
','+EscapedFunctions.ROUND+','+EscapedFunctions.SIGN+
','+EscapedFunctions.SIN+','+EscapedFunctions.SQRT+
','+EscapedFunctions.TAN+','+EscapedFunctions.TRUNCATE;
}
 
public String getStringFunctions() throws SQLException
{
String funcs = EscapedFunctions.ASCII+','+EscapedFunctions.CHAR+
','+EscapedFunctions.CONCAT+
','+EscapedFunctions.LCASE+','+EscapedFunctions.LEFT+
','+EscapedFunctions.LENGTH+
','+EscapedFunctions.LTRIM+','+EscapedFunctions.REPEAT+
','+EscapedFunctions.RTRIM+
','+EscapedFunctions.SPACE+','+EscapedFunctions.SUBSTRING+
','+EscapedFunctions.UCASE;
 
// Currently these don't work correctly with parameterized
// arguments, so leave them out. They reorder the arguments
// when rewriting the query, but no translation layer is provided,
// so a setObject(N, obj) will not go to the correct parameter.
//','+EscapedFunctions.INSERT+','+EscapedFunctions.LOCATE+
//','+EscapedFunctions.RIGHT+
if (connection.haveMinimumServerVersion("7.3")) {
funcs += ','+EscapedFunctions.REPLACE;
}
 
return funcs;
}
 
public String getSystemFunctions() throws SQLException
{
if (connection.haveMinimumServerVersion("7.3")){
return EscapedFunctions.DATABASE+','+EscapedFunctions.IFNULL+
','+EscapedFunctions.USER;
} else {
return EscapedFunctions.IFNULL+
','+EscapedFunctions.USER;
}
}
 
public String getTimeDateFunctions() throws SQLException
{
String timeDateFuncs = EscapedFunctions.CURDATE+','+EscapedFunctions.CURTIME+
','+EscapedFunctions.DAYNAME+','+EscapedFunctions.DAYOFMONTH+
','+EscapedFunctions.DAYOFWEEK+','+EscapedFunctions.DAYOFYEAR+
','+EscapedFunctions.HOUR+','+EscapedFunctions.MINUTE+
','+EscapedFunctions.MONTH+
','+EscapedFunctions.MONTHNAME+','+EscapedFunctions.NOW+
','+EscapedFunctions.QUARTER+','+EscapedFunctions.SECOND+
','+EscapedFunctions.WEEK+','+EscapedFunctions.YEAR;
 
if (connection.haveMinimumServerVersion("8.0")) {
timeDateFuncs += ','+EscapedFunctions.TIMESTAMPADD;
}
 
//+','+EscapedFunctions.TIMESTAMPDIFF;
 
return timeDateFuncs;
}
 
/*
* This is the string that can be used to escape '_' and '%' in
* a search string pattern style catalog search parameters
*
* @return the string used to escape wildcard characters
* @exception SQLException if a database access error occurs
*/
public String getSearchStringEscape() throws SQLException
{
// This method originally returned "\\\\" assuming that it
// would be fed directly into pg's input parser so it would
// need two backslashes. This isn't how it's supposed to be
// used though. If passed as a PreparedStatement parameter
// or fed to a DatabaseMetaData method then double backslashes
// are incorrect. If you're feeding something directly into
// a query you are responsible for correctly escaping it.
// With 8.2+ this escaping is a little trickier because you
// must know the setting of standard_conforming_strings, but
// that's not our problem.
 
return "\\";
}
 
/*
* Get all the "extra" characters that can be used in unquoted
* identifier names (those beyond a-zA-Z0-9 and _)
*
* <p>Postgresql allows any high-bit character to be used
* in an unquoted identifer, so we can't possibly list them all.
*
* From the file src/backend/parser/scan.l, an identifier is
* ident_start [A-Za-z\200-\377_]
* ident_cont [A-Za-z\200-\377_0-9\$]
* identifier {ident_start}{ident_cont}*
*
* @return a string containing the extra characters
* @exception SQLException if a database access error occurs
*/
public String getExtraNameCharacters() throws SQLException
{
return "";
}
 
/*
* Is "ALTER TABLE" with an add column supported?
* Yes for PostgreSQL 6.1
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsAlterTableWithAddColumn() throws SQLException
{
return true;
}
 
/*
* Is "ALTER TABLE" with a drop column supported?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsAlterTableWithDropColumn() throws SQLException
{
return connection.haveMinimumServerVersion("7.3");
}
 
/*
* Is column aliasing supported?
*
* <p>If so, the SQL AS clause can be used to provide names for
* computed columns or to provide alias names for columns as
* required. A JDBC Compliant driver always returns true.
*
* <p>e.g.
*
* <br><pre>
* select count(C) as C_COUNT from T group by C;
*
* </pre><br>
* should return a column named as C_COUNT instead of count(C)
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsColumnAliasing() throws SQLException
{
return true;
}
 
/*
* Are concatenations between NULL and non-NULL values NULL? A
* JDBC Compliant driver always returns true
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean nullPlusNonNullIsNull() throws SQLException
{
return true;
}
 
public boolean supportsConvert() throws SQLException
{
return false;
}
 
public boolean supportsConvert(int fromType, int toType) throws SQLException
{
return false;
}
 
/*
* Are table correlation names supported? A JDBC Compliant
* driver always returns true.
*
* @return true if so; false otherwise
* @exception SQLException - if a database access error occurs
*/
public boolean supportsTableCorrelationNames() throws SQLException
{
return true;
}
 
/*
* If table correlation names are supported, are they restricted to
* be different from the names of the tables?
*
* @return true if so; false otherwise
* @exception SQLException - if a database access error occurs
*/
public boolean supportsDifferentTableCorrelationNames() throws SQLException
{
return false;
}
 
/*
* Are expressions in "ORDER BY" lists supported?
*
* <br>e.g. select * from t order by a + b;
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsExpressionsInOrderBy() throws SQLException
{
return true;
}
 
/*
* Can an "ORDER BY" clause use columns not in the SELECT?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsOrderByUnrelated() throws SQLException
{
return connection.haveMinimumServerVersion("6.4");
}
 
/*
* Is some form of "GROUP BY" clause supported?
* I checked it, and yes it is.
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsGroupBy() throws SQLException
{
return true;
}
 
/*
* Can a "GROUP BY" clause use columns not in the SELECT?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsGroupByUnrelated() throws SQLException
{
return connection.haveMinimumServerVersion("6.4");
}
 
/*
* Can a "GROUP BY" clause add columns not in the SELECT provided
* it specifies all the columns in the SELECT? Does anyone actually
* understand what they mean here?
*
* (I think this is a subset of the previous function. -- petere)
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsGroupByBeyondSelect() throws SQLException
{
return connection.haveMinimumServerVersion("6.4");
}
 
/*
* Is the escape character in "LIKE" clauses supported? A
* JDBC compliant driver always returns true.
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsLikeEscapeClause() throws SQLException
{
return connection.haveMinimumServerVersion("7.1");
}
 
/*
* Are multiple ResultSets from a single execute supported?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsMultipleResultSets() throws SQLException
{
return true;
}
 
/*
* Can we have multiple transactions open at once (on different
* connections?)
* I guess we can have, since Im relying on it.
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsMultipleTransactions() throws SQLException
{
return true;
}
 
/*
* Can columns be defined as non-nullable. A JDBC Compliant driver
* always returns true.
*
* <p>This changed from false to true in v6.2 of the driver, as this
* support was added to the backend.
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsNonNullableColumns() throws SQLException
{
return true;
}
 
/*
* Does this driver support the minimum ODBC SQL grammar. This
* grammar is defined at:
*
* <p><a href="http://www.microsoft.com/msdn/sdk/platforms/doc/odbc/src/intropr.htm">http://www.microsoft.com/msdn/sdk/platforms/doc/odbc/src/intropr.htm</a>
*
* <p>In Appendix C. From this description, we seem to support the
* ODBC minimal (Level 0) grammar.
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsMinimumSQLGrammar() throws SQLException
{
return true;
}
 
/*
* Does this driver support the Core ODBC SQL grammar. We need
* SQL-92 conformance for this.
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsCoreSQLGrammar() throws SQLException
{
return false;
}
 
/*
* Does this driver support the Extended (Level 2) ODBC SQL
* grammar. We don't conform to the Core (Level 1), so we can't
* conform to the Extended SQL Grammar.
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsExtendedSQLGrammar() throws SQLException
{
return false;
}
 
/*
* Does this driver support the ANSI-92 entry level SQL grammar?
* All JDBC Compliant drivers must return true. We currently
* report false until 'schema' support is added. Then this
* should be changed to return true, since we will be mostly
* compliant (probably more compliant than many other databases)
* And since this is a requirement for all JDBC drivers we
* need to get to the point where we can return true.
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsANSI92EntryLevelSQL() throws SQLException
{
return connection.haveMinimumServerVersion("7.3");
}
 
/*
* Does this driver support the ANSI-92 intermediate level SQL
* grammar?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsANSI92IntermediateSQL() throws SQLException
{
return false;
}
 
/*
* Does this driver support the ANSI-92 full SQL grammar?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsANSI92FullSQL() throws SQLException
{
return false;
}
 
/*
* Is the SQL Integrity Enhancement Facility supported?
* Our best guess is that this means support for constraints
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsIntegrityEnhancementFacility() throws SQLException
{
return true;
}
 
/*
* Is some form of outer join supported?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsOuterJoins() throws SQLException
{
return connection.haveMinimumServerVersion("7.1");
}
 
/*
* Are full nexted outer joins supported?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsFullOuterJoins() throws SQLException
{
return connection.haveMinimumServerVersion("7.1");
}
 
/*
* Is there limited support for outer joins?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsLimitedOuterJoins() throws SQLException
{
return connection.haveMinimumServerVersion("7.1");
}
 
/*
* What is the database vendor's preferred term for "schema"?
* PostgreSQL doesn't have schemas, but when it does, we'll use the
* term "schema".
*
* @return the vendor term
* @exception SQLException if a database access error occurs
*/
public String getSchemaTerm() throws SQLException
{
return "schema";
}
 
/*
* What is the database vendor's preferred term for "procedure"?
* Traditionally, "function" has been used.
*
* @return the vendor term
* @exception SQLException if a database access error occurs
*/
public String getProcedureTerm() throws SQLException
{
return "function";
}
 
/*
* What is the database vendor's preferred term for "catalog"?
*
* @return the vendor term
* @exception SQLException if a database access error occurs
*/
public String getCatalogTerm() throws SQLException
{
return "database";
}
 
/*
* Does a catalog appear at the start of a qualified table name?
* (Otherwise it appears at the end).
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean isCatalogAtStart() throws SQLException
{
return true;
}
 
/*
* What is the Catalog separator.
*
* @return the catalog separator string
* @exception SQLException if a database access error occurs
*/
public String getCatalogSeparator() throws SQLException
{
return ".";
}
 
/*
* Can a schema name be used in a data manipulation statement?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsSchemasInDataManipulation() throws SQLException
{
return connection.haveMinimumServerVersion("7.3");
}
 
/*
* Can a schema name be used in a procedure call statement?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsSchemasInProcedureCalls() throws SQLException
{
return connection.haveMinimumServerVersion("7.3");
}
 
/*
* Can a schema be used in a table definition statement?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsSchemasInTableDefinitions() throws SQLException
{
return connection.haveMinimumServerVersion("7.3");
}
 
/*
* Can a schema name be used in an index definition statement?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsSchemasInIndexDefinitions() throws SQLException
{
return connection.haveMinimumServerVersion("7.3");
}
 
/*
* Can a schema name be used in a privilege definition statement?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException
{
return connection.haveMinimumServerVersion("7.3");
}
 
/*
* Can a catalog name be used in a data manipulation statement?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsCatalogsInDataManipulation() throws SQLException
{
return false;
}
 
/*
* Can a catalog name be used in a procedure call statement?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsCatalogsInProcedureCalls() throws SQLException
{
return false;
}
 
/*
* Can a catalog name be used in a table definition statement?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsCatalogsInTableDefinitions() throws SQLException
{
return false;
}
 
/*
* Can a catalog name be used in an index definition?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsCatalogsInIndexDefinitions() throws SQLException
{
return false;
}
 
/*
* Can a catalog name be used in a privilege definition statement?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException
{
return false;
}
 
/*
* We support cursors for gets only it seems. I dont see a method
* to get a positioned delete.
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsPositionedDelete() throws SQLException
{
return false; // For now...
}
 
/*
* Is positioned UPDATE supported?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsPositionedUpdate() throws SQLException
{
return false; // For now...
}
 
/*
* Is SELECT for UPDATE supported?
*
* @return true if so; false otherwise
* @exception SQLException - if a database access error occurs
*/
public boolean supportsSelectForUpdate() throws SQLException
{
return connection.haveMinimumServerVersion("6.5");
}
 
/*
* Are stored procedure calls using the stored procedure escape
* syntax supported?
*
* @return true if so; false otherwise
* @exception SQLException - if a database access error occurs
*/
public boolean supportsStoredProcedures() throws SQLException
{
return true;
}
 
/*
* Are subqueries in comparison expressions supported? A JDBC
* Compliant driver always returns true.
*
* @return true if so; false otherwise
* @exception SQLException - if a database access error occurs
*/
public boolean supportsSubqueriesInComparisons() throws SQLException
{
return true;
}
 
/*
* Are subqueries in 'exists' expressions supported? A JDBC
* Compliant driver always returns true.
*
* @return true if so; false otherwise
* @exception SQLException - if a database access error occurs
*/
public boolean supportsSubqueriesInExists() throws SQLException
{
return true;
}
 
/*
* Are subqueries in 'in' statements supported? A JDBC
* Compliant driver always returns true.
*
* @return true if so; false otherwise
* @exception SQLException - if a database access error occurs
*/
public boolean supportsSubqueriesInIns() throws SQLException
{
return true;
}
 
/*
* Are subqueries in quantified expressions supported? A JDBC
* Compliant driver always returns true.
*
* (No idea what this is, but we support a good deal of
* subquerying.)
*
* @return true if so; false otherwise
* @exception SQLException - if a database access error occurs
*/
public boolean supportsSubqueriesInQuantifieds() throws SQLException
{
return true;
}
 
/*
* Are correlated subqueries supported? A JDBC Compliant driver
* always returns true.
*
* (a.k.a. subselect in from?)
*
* @return true if so; false otherwise
* @exception SQLException - if a database access error occurs
*/
public boolean supportsCorrelatedSubqueries() throws SQLException
{
return connection.haveMinimumServerVersion("7.1");
}
 
/*
* Is SQL UNION supported?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsUnion() throws SQLException
{
return true; // since 6.3
}
 
/*
* Is SQL UNION ALL supported?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsUnionAll() throws SQLException
{
return connection.haveMinimumServerVersion("7.1");
}
 
/*
* In PostgreSQL, Cursors are only open within transactions.
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsOpenCursorsAcrossCommit() throws SQLException
{
return false;
}
 
/*
* Do we support open cursors across multiple transactions?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsOpenCursorsAcrossRollback() throws SQLException
{
return false;
}
 
/*
* Can statements remain open across commits? They may, but
* this driver cannot guarentee that. In further reflection.
* we are talking a Statement object here, so the answer is
* yes, since the Statement is only a vehicle to ExecSQL()
*
* @return true if they always remain open; false otherwise
* @exception SQLException if a database access error occurs
*/
public boolean supportsOpenStatementsAcrossCommit() throws SQLException
{
return true;
}
 
/*
* Can statements remain open across rollbacks? They may, but
* this driver cannot guarentee that. In further contemplation,
* we are talking a Statement object here, so the answer is yes,
* since the Statement is only a vehicle to ExecSQL() in Connection
*
* @return true if they always remain open; false otherwise
* @exception SQLException if a database access error occurs
*/
public boolean supportsOpenStatementsAcrossRollback() throws SQLException
{
return true;
}
 
/*
* How many hex characters can you have in an inline binary literal
*
* @return the max literal length
* @exception SQLException if a database access error occurs
*/
public int getMaxBinaryLiteralLength() throws SQLException
{
return 0; // no limit
}
 
/*
* What is the maximum length for a character literal
* I suppose it is 8190 (8192 - 2 for the quotes)
*
* @return the max literal length
* @exception SQLException if a database access error occurs
*/
public int getMaxCharLiteralLength() throws SQLException
{
return 0; // no limit
}
 
/*
* Whats the limit on column name length.
*
* @return the maximum column name length
* @exception SQLException if a database access error occurs
*/
public int getMaxColumnNameLength() throws SQLException
{
return getMaxNameLength();
}
 
/*
* What is the maximum number of columns in a "GROUP BY" clause?
*
* @return the max number of columns
* @exception SQLException if a database access error occurs
*/
public int getMaxColumnsInGroupBy() throws SQLException
{
return 0; // no limit
}
 
/*
* What's the maximum number of columns allowed in an index?
*
* @return max number of columns
* @exception SQLException if a database access error occurs
*/
public int getMaxColumnsInIndex() throws SQLException
{
return getMaxIndexKeys();
}
 
/*
* What's the maximum number of columns in an "ORDER BY clause?
*
* @return the max columns
* @exception SQLException if a database access error occurs
*/
public int getMaxColumnsInOrderBy() throws SQLException
{
return 0; // no limit
}
 
/*
* What is the maximum number of columns in a "SELECT" list?
*
* @return the max columns
* @exception SQLException if a database access error occurs
*/
public int getMaxColumnsInSelect() throws SQLException
{
return 0; // no limit
}
 
/*
* What is the maximum number of columns in a table? From the
* CREATE TABLE reference page...
*
* <p>"The new class is created as a heap with no initial data. A
* class can have no more than 1600 attributes (realistically,
* this is limited by the fact that tuple sizes must be less than
* 8192 bytes)..."
*
* @return the max columns
* @exception SQLException if a database access error occurs
*/
public int getMaxColumnsInTable() throws SQLException
{
return 1600;
}
 
/*
* How many active connection can we have at a time to this
* database? Well, since it depends on postmaster, which just
* does a listen() followed by an accept() and fork(), its
* basically very high. Unless the system runs out of processes,
* it can be 65535 (the number of aux. ports on a TCP/IP system).
* I will return 8192 since that is what even the largest system
* can realistically handle,
*
* @return the maximum number of connections
* @exception SQLException if a database access error occurs
*/
public int getMaxConnections() throws SQLException
{
return 8192;
}
 
/*
* What is the maximum cursor name length
*
* @return max cursor name length in bytes
* @exception SQLException if a database access error occurs
*/
public int getMaxCursorNameLength() throws SQLException
{
return getMaxNameLength();
}
 
/*
* Retrieves the maximum number of bytes for an index, including all
* of the parts of the index.
*
* @return max index length in bytes, which includes the composite
* of all the constituent parts of the index; a result of zero means
* that there is no limit or the limit is not known
* @exception SQLException if a database access error occurs
*/
public int getMaxIndexLength() throws SQLException
{
return 0; // no limit (larger than an int anyway)
}
 
public int getMaxSchemaNameLength() throws SQLException
{
return getMaxNameLength();
}
 
/*
* What is the maximum length of a procedure name
*
* @return the max name length in bytes
* @exception SQLException if a database access error occurs
*/
public int getMaxProcedureNameLength() throws SQLException
{
return getMaxNameLength();
}
 
public int getMaxCatalogNameLength() throws SQLException
{
return getMaxNameLength();
}
 
/*
* What is the maximum length of a single row?
*
* @return max row size in bytes
* @exception SQLException if a database access error occurs
*/
public int getMaxRowSize() throws SQLException
{
if (connection.haveMinimumServerVersion("7.1"))
return 1073741824; // 1 GB
else
return 8192; // XXX could be altered
}
 
/*
* Did getMaxRowSize() include LONGVARCHAR and LONGVARBINARY
* blobs? We don't handle blobs yet
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean doesMaxRowSizeIncludeBlobs() throws SQLException
{
return false;
}
 
/*
* What is the maximum length of a SQL statement?
*
* @return max length in bytes
* @exception SQLException if a database access error occurs
*/
public int getMaxStatementLength() throws SQLException
{
if (connection.haveMinimumServerVersion("7.0"))
return 0; // actually whatever fits in size_t
else
return 16384;
}
 
/*
* How many active statements can we have open at one time to
* this database? We're only limited by Java heap space really.
*
* @return the maximum
* @exception SQLException if a database access error occurs
*/
public int getMaxStatements() throws SQLException
{
return 0;
}
 
/*
* What is the maximum length of a table name
*
* @return max name length in bytes
* @exception SQLException if a database access error occurs
*/
public int getMaxTableNameLength() throws SQLException
{
return getMaxNameLength();
}
 
/*
* What is the maximum number of tables that can be specified
* in a SELECT?
*
* @return the maximum
* @exception SQLException if a database access error occurs
*/
public int getMaxTablesInSelect() throws SQLException
{
return 0; // no limit
}
 
/*
* What is the maximum length of a user name
*
* @return the max name length in bytes
* @exception SQLException if a database access error occurs
*/
public int getMaxUserNameLength() throws SQLException
{
return getMaxNameLength();
}
 
 
/*
* What is the database's default transaction isolation level?
*
* @return the default isolation level
* @exception SQLException if a database access error occurs
* @see Connection
*/
public int getDefaultTransactionIsolation() throws SQLException
{
return Connection.TRANSACTION_READ_COMMITTED;
}
 
/*
* Are transactions supported? If not, commit and rollback are noops
* and the isolation level is TRANSACTION_NONE. We do support
* transactions.
*
* @return true if transactions are supported
* @exception SQLException if a database access error occurs
*/
public boolean supportsTransactions() throws SQLException
{
return true;
}
 
/*
* Does the database support the given transaction isolation level?
* We only support TRANSACTION_SERIALIZABLE and TRANSACTION_READ_COMMITTED
* before 8.0; from 8.0 READ_UNCOMMITTED and REPEATABLE_READ are accepted aliases
* for READ_COMMITTED.
*
* @param level the values are defined in java.sql.Connection
* @return true if so
* @exception SQLException if a database access error occurs
* @see Connection
*/
public boolean supportsTransactionIsolationLevel(int level) throws SQLException
{
if (level == Connection.TRANSACTION_SERIALIZABLE ||
level == Connection.TRANSACTION_READ_COMMITTED)
return true;
else if (connection.haveMinimumServerVersion("8.0") && (level == Connection.TRANSACTION_READ_UNCOMMITTED || level == Connection.TRANSACTION_REPEATABLE_READ))
return true;
else
return false;
}
 
/*
* Are both data definition and data manipulation transactions
* supported?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException
{
return true;
}
 
/*
* Are only data manipulation statements withing a transaction
* supported?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean supportsDataManipulationTransactionsOnly() throws SQLException
{
return false;
}
 
/*
* Does a data definition statement within a transaction force
* the transaction to commit? I think this means something like:
*
* <p><pre>
* CREATE TABLE T (A INT);
* INSERT INTO T (A) VALUES (2);
* BEGIN;
* UPDATE T SET A = A + 1;
* CREATE TABLE X (A INT);
* SELECT A FROM T INTO X;
* COMMIT;
* </pre><p>
*
* does the CREATE TABLE call cause a commit? The answer is no.
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean dataDefinitionCausesTransactionCommit() throws SQLException
{
return false;
}
 
/*
* Is a data definition statement within a transaction ignored?
*
* @return true if so
* @exception SQLException if a database access error occurs
*/
public boolean dataDefinitionIgnoredInTransactions() throws SQLException
{
return false;
}
 
/**
* Escape single quotes with another single quote, escape backslashes as needed.
*/
protected String escapeQuotes(String s) throws SQLException {
return connection.escapeString(s);
}
 
/*
* Get a description of stored procedures available in a catalog
*
* <p>Only procedure descriptions matching the schema and procedure
* name criteria are returned. They are ordered by PROCEDURE_SCHEM
* and PROCEDURE_NAME
*
* <p>Each procedure description has the following columns:
* <ol>
* <li><b>PROCEDURE_CAT</b> String => procedure catalog (may be null)
* <li><b>PROCEDURE_SCHEM</b> String => procedure schema (may be null)
* <li><b>PROCEDURE_NAME</b> String => procedure name
* <li><b>Field 4</b> reserved (make it null)
* <li><b>Field 5</b> reserved (make it null)
* <li><b>Field 6</b> reserved (make it null)
* <li><b>REMARKS</b> String => explanatory comment on the procedure
* <li><b>PROCEDURE_TYPE</b> short => kind of procedure
* <ul>
* <li> procedureResultUnknown - May return a result
* <li> procedureNoResult - Does not return a result
* <li> procedureReturnsResult - Returns a result
* </ul>
* </ol>
*
* @param catalog - a catalog name; "" retrieves those without a
* catalog; null means drop catalog name from criteria
* @param schemaParrern - a schema name pattern; "" retrieves those
* without a schema - we ignore this parameter
* @param procedureNamePattern - a procedure name pattern
* @return ResultSet - each row is a procedure description
* @exception SQLException if a database access error occurs
*/
public java.sql.ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern) throws SQLException
{
String sql;
if (connection.haveMinimumServerVersion("7.3"))
{
sql = "SELECT NULL AS PROCEDURE_CAT, n.nspname AS PROCEDURE_SCHEM, p.proname AS PROCEDURE_NAME, NULL, NULL, NULL, d.description AS REMARKS, " + java.sql.DatabaseMetaData.procedureReturnsResult + " AS PROCEDURE_TYPE " +
" FROM pg_catalog.pg_namespace n, pg_catalog.pg_proc p " +
" LEFT JOIN pg_catalog.pg_description d ON (p.oid=d.objoid) " +
" LEFT JOIN pg_catalog.pg_class c ON (d.classoid=c.oid AND c.relname='pg_proc') " +
" LEFT JOIN pg_catalog.pg_namespace pn ON (c.relnamespace=pn.oid AND pn.nspname='pg_catalog') " +
" WHERE p.pronamespace=n.oid ";
if (schemaPattern != null && !"".equals(schemaPattern))
{
sql += " AND n.nspname LIKE '" + escapeQuotes(schemaPattern) + "' ";
}
if (procedureNamePattern != null)
{
sql += " AND p.proname LIKE '" + escapeQuotes(procedureNamePattern) + "' ";
}
sql += " ORDER BY PROCEDURE_SCHEM, PROCEDURE_NAME ";
}
else if (connection.haveMinimumServerVersion("7.1"))
{
sql = "SELECT NULL AS PROCEDURE_CAT, NULL AS PROCEDURE_SCHEM, p.proname AS PROCEDURE_NAME, NULL, NULL, NULL, d.description AS REMARKS, " + java.sql.DatabaseMetaData.procedureReturnsResult + " AS PROCEDURE_TYPE " +
" FROM pg_proc p " +
" LEFT JOIN pg_description d ON (p.oid=d.objoid) ";
if (connection.haveMinimumServerVersion("7.2"))
{
sql += " LEFT JOIN pg_class c ON (d.classoid=c.oid AND c.relname='pg_proc') ";
}
if (procedureNamePattern != null)
{
sql += " WHERE p.proname LIKE '" + escapeQuotes(procedureNamePattern) + "' ";
}
sql += " ORDER BY PROCEDURE_NAME ";
}
else
{
sql = "SELECT NULL AS PROCEDURE_CAT, NULL AS PROCEDURE_SCHEM, p.proname AS PROCEDURE_NAME, NULL, NULL, NULL, NULL AS REMARKS, " + java.sql.DatabaseMetaData.procedureReturnsResult + " AS PROCEDURE_TYPE " +
" FROM pg_proc p ";
if (procedureNamePattern != null)
{
sql += " WHERE p.proname LIKE '" + escapeQuotes(procedureNamePattern) + "' ";
}
sql += " ORDER BY PROCEDURE_NAME ";
}
return createMetaDataStatement().executeQuery(sql);
}
 
/*
* Get a description of a catalog's stored procedure parameters
* and result columns.
*
* <p>Only descriptions matching the schema, procedure and parameter
* name criteria are returned. They are ordered by PROCEDURE_SCHEM
* and PROCEDURE_NAME. Within this, the return value, if any, is
* first. Next are the parameter descriptions in call order. The
* column descriptions follow in column number order.
*
* <p>Each row in the ResultSet is a parameter description or column
* description with the following fields:
* <ol>
* <li><b>PROCEDURE_CAT</b> String => procedure catalog (may be null)
* <li><b>PROCEDURE_SCHE</b>M String => procedure schema (may be null)
* <li><b>PROCEDURE_NAME</b> String => procedure name
* <li><b>COLUMN_NAME</b> String => column/parameter name
* <li><b>COLUMN_TYPE</b> Short => kind of column/parameter:
* <ul><li>procedureColumnUnknown - nobody knows
* <li>procedureColumnIn - IN parameter
* <li>procedureColumnInOut - INOUT parameter
* <li>procedureColumnOut - OUT parameter
* <li>procedureColumnReturn - procedure return value
* <li>procedureColumnResult - result column in ResultSet
* </ul>
* <li><b>DATA_TYPE</b> short => SQL type from java.sql.Types
* <li><b>TYPE_NAME</b> String => Data source specific type name
* <li><b>PRECISION</b> int => precision
* <li><b>LENGTH</b> int => length in bytes of data
* <li><b>SCALE</b> short => scale
* <li><b>RADIX</b> short => radix
* <li><b>NULLABLE</b> short => can it contain NULL?
* <ul><li>procedureNoNulls - does not allow NULL values
* <li>procedureNullable - allows NULL values
* <li>procedureNullableUnknown - nullability unknown
* <li><b>REMARKS</b> String => comment describing parameter/column
* </ol>
* @param catalog This is ignored in org.postgresql, advise this is set to null
* @param schemaPattern
* @param procedureNamePattern a procedure name pattern
* @param columnNamePattern a column name pattern, this is currently ignored because postgresql does not name procedure parameters.
* @return each row is a stored procedure parameter or column description
* @exception SQLException if a database-access error occurs
* @see #getSearchStringEscape
*/
// Implementation note: This is required for Borland's JBuilder to work
public java.sql.ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern) throws SQLException
{
Field f[] = new Field[13];
Vector v = new Vector(); // The new ResultSet tuple stuff
 
f[0] = new Field("PROCEDURE_CAT", Oid.VARCHAR);
f[1] = new Field("PROCEDURE_SCHEM", Oid.VARCHAR);
f[2] = new Field("PROCEDURE_NAME", Oid.VARCHAR);
f[3] = new Field("COLUMN_NAME", Oid.VARCHAR);
f[4] = new Field("COLUMN_TYPE", Oid.INT2);
f[5] = new Field("DATA_TYPE", Oid.INT2);
f[6] = new Field("TYPE_NAME", Oid.VARCHAR);
f[7] = new Field("PRECISION", Oid.INT4);
f[8] = new Field("LENGTH", Oid.INT4);
f[9] = new Field("SCALE", Oid.INT2);
f[10] = new Field("RADIX", Oid.INT2);
f[11] = new Field("NULLABLE", Oid.INT2);
f[12] = new Field("REMARKS", Oid.VARCHAR);
 
String sql;
if (connection.haveMinimumServerVersion("7.3"))
{
sql = "SELECT n.nspname,p.proname,p.prorettype,p.proargtypes, t.typtype,t.typrelid ";
 
if (connection.haveMinimumServerVersion("8.1"))
sql += ", p.proargnames, p.proargmodes, p.proallargtypes ";
else if (connection.haveMinimumServerVersion("8.0"))
sql += ", p.proargnames, NULL AS proargmodes, NULL AS proallargtypes ";
else
sql += ", NULL AS proargnames, NULL AS proargmodes, NULL AS proallargtypes ";
 
sql += " FROM pg_catalog.pg_proc p, pg_catalog.pg_namespace n, pg_catalog.pg_type t " +
" WHERE p.pronamespace=n.oid AND p.prorettype=t.oid ";
if (schemaPattern != null && !"".equals(schemaPattern))
{
sql += " AND n.nspname LIKE '" + escapeQuotes(schemaPattern) + "' ";
}
if (procedureNamePattern != null)
{
sql += " AND p.proname LIKE '" + escapeQuotes(procedureNamePattern) + "' ";
}
sql += " ORDER BY n.nspname, p.proname ";
}
else
{
sql = "SELECT NULL AS nspname,p.proname,p.prorettype,p.proargtypes,t.typtype,t.typrelid, NULL AS proargnames, NULL AS proargmodes, NULL AS proallargtypes " +
" FROM pg_proc p,pg_type t " +
" WHERE p.prorettype=t.oid ";
if (procedureNamePattern != null)
{
sql += " AND p.proname LIKE '" + escapeQuotes(procedureNamePattern) + "' ";
}
sql += " ORDER BY p.proname ";
}
 
ResultSet rs = connection.createStatement().executeQuery(sql);
while (rs.next())
{
byte schema[] = rs.getBytes("nspname");
byte procedureName[] = rs.getBytes("proname");
int returnType = (int)rs.getLong("prorettype");
String returnTypeType = rs.getString("typtype");
int returnTypeRelid = (int)rs.getLong("typrelid");
 
String strArgTypes = rs.getString("proargtypes");
StringTokenizer st = new StringTokenizer(strArgTypes);
Vector argTypes = new Vector();
while (st.hasMoreTokens())
{
argTypes.addElement(new Long(st.nextToken()));
}
 
String argNames[] = null;
Array argNamesArray = rs.getArray("proargnames");
if (argNamesArray != null)
argNames = (String[])argNamesArray.getArray();
 
String argModes[] = null;
Array argModesArray = rs.getArray("proargmodes");
if (argModesArray != null)
argModes = (String[])argModesArray.getArray();
 
int numArgs = argTypes.size();
 
Long allArgTypes[] = null;
Array allArgTypesArray = rs.getArray("proallargtypes");
if (allArgTypesArray != null) {
// Depending on what the user has selected we'll get
// either long[] or Long[] back, and there's no
// obvious way for the driver to override this for
// it's own usage.
if (connection.haveMinimumCompatibleVersion("8.3")) {
allArgTypes = (Long[])allArgTypesArray.getArray();
} else {
long tempAllArgTypes[] = (long[])allArgTypesArray.getArray();
allArgTypes = new Long[tempAllArgTypes.length];
for (int i=0; i<tempAllArgTypes.length; i++) {
allArgTypes[i] = new Long(tempAllArgTypes[i]);
}
}
numArgs = allArgTypes.length;
}
 
// decide if we are returning a single column result.
if (returnTypeType.equals("b") || returnTypeType.equals("d") || (returnTypeType.equals("p") && argModesArray == null))
{
byte[][] tuple = new byte[13][];
tuple[0] = null;
tuple[1] = schema;
tuple[2] = procedureName;
tuple[3] = connection.encodeString("returnValue");
tuple[4] = connection.encodeString(Integer.toString(java.sql.DatabaseMetaData.procedureColumnReturn));
tuple[5] = connection.encodeString(Integer.toString(connection.getTypeInfo().getSQLType(returnType)));
tuple[6] = connection.encodeString(connection.getTypeInfo().getPGType(returnType));
tuple[7] = null;
tuple[8] = null;
tuple[9] = null;
tuple[10] = null;
tuple[11] = connection.encodeString(Integer.toString(java.sql.DatabaseMetaData.procedureNullableUnknown));
tuple[12] = null;
v.addElement(tuple);
}
 
// Add a row for each argument.
for (int i = 0; i < numArgs; i++)
{
byte[][] tuple = new byte[13][];
tuple[0] = null;
tuple[1] = schema;
tuple[2] = procedureName;
 
if (argNames != null)
tuple[3] = connection.encodeString(argNames[i]);
else
tuple[3] = connection.encodeString("$" + (i + 1));
 
int columnMode = DatabaseMetaData.procedureColumnIn;
if (argModes != null && argModes[i].equals("o"))
columnMode = DatabaseMetaData.procedureColumnOut;
else if (argModes != null && argModes[i].equals("b"))
columnMode = DatabaseMetaData.procedureColumnInOut;
 
tuple[4] = connection.encodeString(Integer.toString(columnMode));
 
int argOid;
if (allArgTypes != null)
argOid = allArgTypes[i].intValue();
else
argOid = ((Long)argTypes.elementAt(i)).intValue();
 
tuple[5] = connection.encodeString(Integer.toString(connection.getTypeInfo().getSQLType(argOid)));
tuple[6] = connection.encodeString(connection.getTypeInfo().getPGType(argOid));
tuple[7] = null;
tuple[8] = null;
tuple[9] = null;
tuple[10] = null;
tuple[11] = connection.encodeString(Integer.toString(DatabaseMetaData.procedureNullableUnknown));
tuple[12] = null;
v.addElement(tuple);
}
 
// if we are returning a multi-column result.
if (returnTypeType.equals("c") || (returnTypeType.equals("p") && argModesArray != null))
{
String columnsql = "SELECT a.attname,a.atttypid FROM ";
if (connection.haveMinimumServerVersion("7.3")) {
columnsql += "pg_catalog.";
}
columnsql += "pg_attribute a WHERE a.attrelid = " + returnTypeRelid + " AND a.attnum > 0 ORDER BY a.attnum ";
ResultSet columnrs = connection.createStatement().executeQuery(columnsql);
while (columnrs.next())
{
int columnTypeOid = (int)columnrs.getLong("atttypid");
byte[][] tuple = new byte[13][];
tuple[0] = null;
tuple[1] = schema;
tuple[2] = procedureName;
tuple[3] = columnrs.getBytes("attname");
tuple[4] = connection.encodeString(Integer.toString(java.sql.DatabaseMetaData.procedureColumnResult));
tuple[5] = connection.encodeString(Integer.toString(connection.getTypeInfo().getSQLType(columnTypeOid)));
tuple[6] = connection.encodeString(connection.getTypeInfo().getPGType(columnTypeOid));
tuple[7] = null;
tuple[8] = null;
tuple[9] = null;
tuple[10] = null;
tuple[11] = connection.encodeString(Integer.toString(java.sql.DatabaseMetaData.procedureNullableUnknown));
tuple[12] = null;
v.addElement(tuple);
}
columnrs.close();
}
}
rs.close();
 
return (ResultSet)((BaseStatement)createMetaDataStatement()).createDriverResultSet(f, v);
}
 
/*
* Get a description of tables available in a catalog.
*
* <p>Only table descriptions matching the catalog, schema, table
* name and type criteria are returned. They are ordered by
* TABLE_TYPE, TABLE_SCHEM and TABLE_NAME.
*
* <p>Each table description has the following columns:
*
* <ol>
* <li><b>TABLE_CAT</b> String => table catalog (may be null)
* <li><b>TABLE_SCHEM</b> String => table schema (may be null)
* <li><b>TABLE_NAME</b> String => table name
* <li><b>TABLE_TYPE</b> String => table type. Typical types are "TABLE",
* "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY", "LOCAL
* TEMPORARY", "ALIAS", "SYNONYM".
* <li><b>REMARKS</b> String => explanatory comment on the table
* </ol>
*
* <p>The valid values for the types parameter are:
* "TABLE", "INDEX", "SEQUENCE", "VIEW", "TYPE"
* "SYSTEM TABLE", "SYSTEM INDEX", "SYSTEM VIEW",
* "SYSTEM TOAST TABLE", "SYSTEM TOAST INDEX",
* "TEMPORARY TABLE", "TEMPORARY VIEW", "TEMPORARY INDEX",
* "TEMPORARY SEQUENCE".
*
* @param catalog a catalog name; For org.postgresql, this is ignored, and
* should be set to null
* @param schemaPattern a schema name pattern
* @param tableNamePattern a table name pattern. For all tables this should be "%"
* @param types a list of table types to include; null returns
* all types
* @return each row is a table description
* @exception SQLException if a database-access error occurs.
*/
public java.sql.ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String types[]) throws SQLException
{
String select;
String orderby;
String useSchemas;
if (connection.haveMinimumServerVersion("7.3"))
{
useSchemas = "SCHEMAS";
select = "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, c.relname AS TABLE_NAME, " +
" CASE n.nspname ~ '^pg_' OR n.nspname = 'information_schema' " +
" WHEN true THEN CASE " +
" WHEN n.nspname = 'pg_catalog' OR n.nspname = 'information_schema' THEN CASE c.relkind " +
" WHEN 'r' THEN 'SYSTEM TABLE' " +
" WHEN 'v' THEN 'SYSTEM VIEW' " +
" WHEN 'i' THEN 'SYSTEM INDEX' " +
" ELSE NULL " +
" END " +
" WHEN n.nspname = 'pg_toast' THEN CASE c.relkind " +
" WHEN 'r' THEN 'SYSTEM TOAST TABLE' " +
" WHEN 'i' THEN 'SYSTEM TOAST INDEX' " +
" ELSE NULL " +
" END " +
" ELSE CASE c.relkind " +
" WHEN 'r' THEN 'TEMPORARY TABLE' " +
" WHEN 'i' THEN 'TEMPORARY INDEX' " +
" WHEN 'S' THEN 'TEMPORARY SEQUENCE' " +
" WHEN 'v' THEN 'TEMPORARY VIEW' " +
" ELSE NULL " +
" END " +
" END " +
" WHEN false THEN CASE c.relkind " +
" WHEN 'r' THEN 'TABLE' " +
" WHEN 'i' THEN 'INDEX' " +
" WHEN 'S' THEN 'SEQUENCE' " +
" WHEN 'v' THEN 'VIEW' " +
" WHEN 'c' THEN 'TYPE' " +
" ELSE NULL " +
" END " +
" ELSE NULL " +
" END " +
" AS TABLE_TYPE, d.description AS REMARKS " +
" FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c " +
" LEFT JOIN pg_catalog.pg_description d ON (c.oid = d.objoid AND d.objsubid = 0) " +
" LEFT JOIN pg_catalog.pg_class dc ON (d.classoid=dc.oid AND dc.relname='pg_class') " +
" LEFT JOIN pg_catalog.pg_namespace dn ON (dn.oid=dc.relnamespace AND dn.nspname='pg_catalog') " +
" WHERE c.relnamespace = n.oid ";
if (schemaPattern != null && !"".equals(schemaPattern))
{
select += " AND n.nspname LIKE '" + escapeQuotes(schemaPattern) + "' ";
}
orderby = " ORDER BY TABLE_TYPE,TABLE_SCHEM,TABLE_NAME ";
}
else
{
useSchemas = "NOSCHEMAS";
String tableType = "" +
" CASE c.relname ~ '^pg_' " +
" WHEN true THEN CASE c.relname ~ '^pg_toast_' " +
" WHEN true THEN CASE c.relkind " +
" WHEN 'r' THEN 'SYSTEM TOAST TABLE' " +
" WHEN 'i' THEN 'SYSTEM TOAST INDEX' " +
" ELSE NULL " +
" END " +
" WHEN false THEN CASE c.relname ~ '^pg_temp_' " +
" WHEN true THEN CASE c.relkind " +
" WHEN 'r' THEN 'TEMPORARY TABLE' " +
" WHEN 'i' THEN 'TEMPORARY INDEX' " +
" WHEN 'S' THEN 'TEMPORARY SEQUENCE' " +
" WHEN 'v' THEN 'TEMPORARY VIEW' " +
" ELSE NULL " +
" END " +
" WHEN false THEN CASE c.relkind " +
" WHEN 'r' THEN 'SYSTEM TABLE' " +
" WHEN 'v' THEN 'SYSTEM VIEW' " +
" WHEN 'i' THEN 'SYSTEM INDEX' " +
" ELSE NULL " +
" END " +
" ELSE NULL " +
" END " +
" ELSE NULL " +
" END " +
" WHEN false THEN CASE c.relkind " +
" WHEN 'r' THEN 'TABLE' " +
" WHEN 'i' THEN 'INDEX' " +
" WHEN 'S' THEN 'SEQUENCE' " +
" WHEN 'v' THEN 'VIEW' " +
" WHEN 'c' THEN 'TYPE' " +
" ELSE NULL " +
" END " +
" ELSE NULL " +
" END ";
orderby = " ORDER BY TABLE_TYPE,TABLE_NAME ";
if (connection.haveMinimumServerVersion("7.2"))
{
select = "SELECT NULL AS TABLE_CAT, NULL AS TABLE_SCHEM, c.relname AS TABLE_NAME, " + tableType + " AS TABLE_TYPE, d.description AS REMARKS " +
" FROM pg_class c " +
" LEFT JOIN pg_description d ON (c.oid=d.objoid AND d.objsubid = 0) " +
" LEFT JOIN pg_class dc ON (d.classoid = dc.oid AND dc.relname='pg_class') " +
" WHERE true ";
}
else if (connection.haveMinimumServerVersion("7.1"))
{
select = "SELECT NULL AS TABLE_CAT, NULL AS TABLE_SCHEM, c.relname AS TABLE_NAME, " + tableType + " AS TABLE_TYPE, d.description AS REMARKS " +
" FROM pg_class c " +
" LEFT JOIN pg_description d ON (c.oid=d.objoid) " +
" WHERE true ";
}
else
{
select = "SELECT NULL AS TABLE_CAT, NULL AS TABLE_SCHEM, c.relname AS TABLE_NAME, " + tableType + " AS TABLE_TYPE, NULL AS REMARKS " +
" FROM pg_class c " +
" WHERE true ";
}
}
 
if (tableNamePattern != null)
{
select += " AND c.relname LIKE '" + escapeQuotes(tableNamePattern) + "' ";
}
if (types != null) {
select += " AND (false ";
for (int i = 0; i < types.length; i++)
{
Hashtable clauses = (Hashtable)tableTypeClauses.get(types[i]);
if (clauses != null)
{
String clause = (String)clauses.get(useSchemas);
select += " OR ( " + clause + " ) ";
}
}
select += ") ";
}
String sql = select + orderby;
 
return createMetaDataStatement().executeQuery(sql);
}
 
private static final Hashtable tableTypeClauses;
static {
tableTypeClauses = new Hashtable();
Hashtable ht = new Hashtable();
tableTypeClauses.put("TABLE", ht);
ht.put("SCHEMAS", "c.relkind = 'r' AND n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'");
ht.put("NOSCHEMAS", "c.relkind = 'r' AND c.relname !~ '^pg_'");
ht = new Hashtable();
tableTypeClauses.put("VIEW", ht);
ht.put("SCHEMAS", "c.relkind = 'v' AND n.nspname <> 'pg_catalog' AND n.nspname <> 'information_schema'");
ht.put("NOSCHEMAS", "c.relkind = 'v' AND c.relname !~ '^pg_'");
ht = new Hashtable();
tableTypeClauses.put("INDEX", ht);
ht.put("SCHEMAS", "c.relkind = 'i' AND n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'");
ht.put("NOSCHEMAS", "c.relkind = 'i' AND c.relname !~ '^pg_'");
ht = new Hashtable();
tableTypeClauses.put("SEQUENCE", ht);
ht.put("SCHEMAS", "c.relkind = 'S'");
ht.put("NOSCHEMAS", "c.relkind = 'S'");
ht = new Hashtable();
tableTypeClauses.put("TYPE", ht);
ht.put("SCHEMAS", "c.relkind = 'c' AND n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'");
ht.put("NOSCHEMAS", "c.relkind = 'c' AND c.relname !~ '^pg_'");
ht = new Hashtable();
tableTypeClauses.put("SYSTEM TABLE", ht);
ht.put("SCHEMAS", "c.relkind = 'r' AND (n.nspname = 'pg_catalog' OR n.nspname = 'information_schema')");
ht.put("NOSCHEMAS", "c.relkind = 'r' AND c.relname ~ '^pg_' AND c.relname !~ '^pg_toast_' AND c.relname !~ '^pg_temp_'");
ht = new Hashtable();
tableTypeClauses.put("SYSTEM TOAST TABLE", ht);
ht.put("SCHEMAS", "c.relkind = 'r' AND n.nspname = 'pg_toast'");
ht.put("NOSCHEMAS", "c.relkind = 'r' AND c.relname ~ '^pg_toast_'");
ht = new Hashtable();
tableTypeClauses.put("SYSTEM TOAST INDEX", ht);
ht.put("SCHEMAS", "c.relkind = 'i' AND n.nspname = 'pg_toast'");
ht.put("NOSCHEMAS", "c.relkind = 'i' AND c.relname ~ '^pg_toast_'");
ht = new Hashtable();
tableTypeClauses.put("SYSTEM VIEW", ht);
ht.put("SCHEMAS", "c.relkind = 'v' AND (n.nspname = 'pg_catalog' OR n.nspname = 'information_schema') ");
ht.put("NOSCHEMAS", "c.relkind = 'v' AND c.relname ~ '^pg_'");
ht = new Hashtable();
tableTypeClauses.put("SYSTEM INDEX", ht);
ht.put("SCHEMAS", "c.relkind = 'i' AND (n.nspname = 'pg_catalog' OR n.nspname = 'information_schema') ");
ht.put("NOSCHEMAS", "c.relkind = 'v' AND c.relname ~ '^pg_' AND c.relname !~ '^pg_toast_' AND c.relname !~ '^pg_temp_'");
ht = new Hashtable();
tableTypeClauses.put("TEMPORARY TABLE", ht);
ht.put("SCHEMAS", "c.relkind = 'r' AND n.nspname ~ '^pg_temp_' ");
ht.put("NOSCHEMAS", "c.relkind = 'r' AND c.relname ~ '^pg_temp_' ");
ht = new Hashtable();
tableTypeClauses.put("TEMPORARY INDEX", ht);
ht.put("SCHEMAS", "c.relkind = 'i' AND n.nspname ~ '^pg_temp_' ");
ht.put("NOSCHEMAS", "c.relkind = 'i' AND c.relname ~ '^pg_temp_' ");
ht = new Hashtable();
tableTypeClauses.put("TEMPORARY VIEW", ht);
ht.put("SCHEMAS", "c.relkind = 'v' AND n.nspname ~ '^pg_temp_' ");
ht.put("NOSCHEMAS", "c.relkind = 'v' AND c.relname ~ '^pg_temp_' ");
ht = new Hashtable();
tableTypeClauses.put("TEMPORARY SEQUENCE", ht);
ht.put("SCHEMAS", "c.relkind = 'S' AND n.nspname ~ '^pg_temp_' ");
ht.put("NOSCHEMAS", "c.relkind = 'S' AND c.relname ~ '^pg_temp_' ");
}
 
/*
* Get the schema names available in this database. The results
* are ordered by schema name.
*
* <P>The schema column is:
* <OL>
* <LI><B>TABLE_SCHEM</B> String => schema name
* </OL>
*
* @return ResultSet each row has a single String column that is a
* schema name
*/
public java.sql.ResultSet getSchemas() throws SQLException
{
String sql;
if (connection.haveMinimumServerVersion("7.3"))
{
sql = "SELECT nspname AS TABLE_SCHEM FROM pg_catalog.pg_namespace WHERE nspname <> 'pg_toast' AND nspname !~ '^pg_temp_' ORDER BY TABLE_SCHEM";
}
else
{
sql = "SELECT ''::text AS TABLE_SCHEM ORDER BY TABLE_SCHEM";
}
return createMetaDataStatement().executeQuery(sql);
}
 
/*
* Get the catalog names available in this database. The results
* are ordered by catalog name.
*
* Postgresql does not support multiple catalogs from a single
* connection, so to reduce confusion we only return the current
* catalog.
*
* <P>The catalog column is:
* <OL>
* <LI><B>TABLE_CAT</B> String => catalog name
* </OL>
*
* @return ResultSet each row has a single String column that is a
* catalog name
*/
public java.sql.ResultSet getCatalogs() throws SQLException
{
Field f[] = new Field[1];
Vector v = new Vector();
f[0] = new Field("TABLE_CAT", Oid.VARCHAR);
byte[][] tuple = new byte[1][];
tuple[0] = connection.encodeString(connection.getCatalog());
v.addElement(tuple);
 
return (ResultSet) ((BaseStatement)createMetaDataStatement()).createDriverResultSet(f, v);
}
 
/*
* Get the table types available in this database. The results
* are ordered by table type.
*
* <P>The table type is:
* <OL>
* <LI><B>TABLE_TYPE</B> String => table type. Typical types are "TABLE",
* "VIEW", "SYSTEM TABLE", "GLOBAL TEMPORARY",
* "LOCAL TEMPORARY", "ALIAS", "SYNONYM".
* </OL>
*
* @return ResultSet each row has a single String column that is a
* table type
*/
public java.sql.ResultSet getTableTypes() throws SQLException
{
String types[] = new String[tableTypeClauses.size()];
Enumeration e = tableTypeClauses.keys();
int i = 0;
while (e.hasMoreElements())
{
types[i++] = (String)e.nextElement();
}
sortStringArray(types);
 
Field f[] = new Field[1];
Vector v = new Vector();
f[0] = new Field("TABLE_TYPE", Oid.VARCHAR);
for (i = 0; i < types.length; i++)
{
byte[][] tuple = new byte[1][];
tuple[0] = connection.encodeString(types[i]);
v.addElement(tuple);
}
 
return (ResultSet) ((BaseStatement)createMetaDataStatement()).createDriverResultSet(f, v);
}
 
protected java.sql.ResultSet getColumns(int jdbcVersion, String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException
{
int numberOfFields;
if (jdbcVersion >= 4) {
numberOfFields = 23;
} else if (jdbcVersion >= 3) {
numberOfFields = 22;
} else {
numberOfFields = 18;
}
Vector v = new Vector(); // The new ResultSet tuple stuff
Field f[] = new Field[numberOfFields]; // The field descriptors for the new ResultSet
 
f[0] = new Field("TABLE_CAT", Oid.VARCHAR);
f[1] = new Field("TABLE_SCHEM", Oid.VARCHAR);
f[2] = new Field("TABLE_NAME", Oid.VARCHAR);
f[3] = new Field("COLUMN_NAME", Oid.VARCHAR);
f[4] = new Field("DATA_TYPE", Oid.INT2);
f[5] = new Field("TYPE_NAME", Oid.VARCHAR);
f[6] = new Field("COLUMN_SIZE", Oid.INT4);
f[7] = new Field("BUFFER_LENGTH", Oid.VARCHAR);
f[8] = new Field("DECIMAL_DIGITS", Oid.INT4);
f[9] = new Field("NUM_PREC_RADIX", Oid.INT4);
f[10] = new Field("NULLABLE", Oid.INT4);
f[11] = new Field("REMARKS", Oid.VARCHAR);
f[12] = new Field("COLUMN_DEF", Oid.VARCHAR);
f[13] = new Field("SQL_DATA_TYPE", Oid.INT4);
f[14] = new Field("SQL_DATETIME_SUB", Oid.INT4);
f[15] = new Field("CHAR_OCTET_LENGTH", Oid.VARCHAR);
f[16] = new Field("ORDINAL_POSITION", Oid.INT4);
f[17] = new Field("IS_NULLABLE", Oid.VARCHAR);
 
if (jdbcVersion >= 3) {
f[18] = new Field("SCOPE_CATLOG", Oid.VARCHAR);
f[19] = new Field("SCOPE_SCHEMA", Oid.VARCHAR);
f[20] = new Field("SCOPE_TABLE", Oid.VARCHAR);
f[21] = new Field("SOURCE_DATA_TYPE", Oid.INT2);
}
 
if (jdbcVersion >= 4) {
f[22] = new Field("IS_AUTOINCREMENT", Oid.VARCHAR);
}
 
String sql;
if (connection.haveMinimumServerVersion("7.3"))
{
// a.attnum isn't decremented when preceding columns are dropped,
// so the only way to calculate the correct column number is with
// window functions, new in 8.4.
//
// We want to push as much predicate information below the window
// function as possible (schema/table names), but must leave
// column name outside so we correctly count the other columns.
//
if (connection.haveMinimumServerVersion("8.4"))
sql = "SELECT * FROM (";
else
sql = "";
 
sql += "SELECT n.nspname,c.relname,a.attname,a.atttypid,a.attnotnull,a.atttypmod,a.attlen,";
if (connection.haveMinimumServerVersion("8.4"))
sql += "row_number() OVER (PARTITION BY a.attrelid ORDER BY a.attnum) AS attnum, ";
else
sql += "a.attnum,";
sql += "pg_catalog.pg_get_expr(def.adbin, def.adrelid) AS adsrc,dsc.description,t.typbasetype,t.typtype " +
" FROM pg_catalog.pg_namespace n " +
" JOIN pg_catalog.pg_class c ON (c.relnamespace = n.oid) " +
" JOIN pg_catalog.pg_attribute a ON (a.attrelid=c.oid) " +
" JOIN pg_catalog.pg_type t ON (a.atttypid = t.oid) " +
" LEFT JOIN pg_catalog.pg_attrdef def ON (a.attrelid=def.adrelid AND a.attnum = def.adnum) " +
" LEFT JOIN pg_catalog.pg_description dsc ON (c.oid=dsc.objoid AND a.attnum = dsc.objsubid) " +
" LEFT JOIN pg_catalog.pg_class dc ON (dc.oid=dsc.classoid AND dc.relname='pg_class') " +
" LEFT JOIN pg_catalog.pg_namespace dn ON (dc.relnamespace=dn.oid AND dn.nspname='pg_catalog') " +
" WHERE a.attnum > 0 AND NOT a.attisdropped ";
 
if (schemaPattern != null && !"".equals(schemaPattern))
{
sql += " AND n.nspname LIKE '" + escapeQuotes(schemaPattern) + "' ";
}
 
if (tableNamePattern != null && !"".equals(tableNamePattern))
{
sql += " AND c.relname LIKE '" + escapeQuotes(tableNamePattern) + "' ";
}
 
if (connection.haveMinimumServerVersion("8.4"))
sql += ") c WHERE true ";
 
}
else if (connection.haveMinimumServerVersion("7.2"))
{
sql = "SELECT NULL::text AS nspname,c.relname,a.attname,a.atttypid,a.attnotnull,a.atttypmod,a.attlen,a.attnum,pg_get_expr(def.adbin,def.adrelid) AS adsrc,dsc.description,NULL::oid AS typbasetype,t.typtype " +
" FROM pg_class c " +
" JOIN pg_attribute a ON (a.attrelid=c.oid) " +
" JOIN pg_type t ON (a.atttypid = t.oid) " +
" LEFT JOIN pg_attrdef def ON (a.attrelid=def.adrelid AND a.attnum = def.adnum) " +
" LEFT JOIN pg_description dsc ON (c.oid=dsc.objoid AND a.attnum = dsc.objsubid) " +
" LEFT JOIN pg_class dc ON (dc.oid=dsc.classoid AND dc.relname='pg_class') " +
" WHERE a.attnum > 0 ";
}
else if (connection.haveMinimumServerVersion("7.1"))
{
sql = "SELECT NULL::text AS nspname,c.relname,a.attname,a.atttypid,a.attnotnull,a.atttypmod,a.attlen,a.attnum,def.adsrc,dsc.description,NULL::oid AS typbasetype, 'b' AS typtype " +
" FROM pg_class c " +
" JOIN pg_attribute a ON (a.attrelid=c.oid) " +
" LEFT JOIN pg_attrdef def ON (a.attrelid=def.adrelid AND a.attnum = def.adnum) " +
" LEFT JOIN pg_description dsc ON (a.oid=dsc.objoid) " +
" WHERE a.attnum > 0 ";
}
else
{
// if < 7.1 then don't get defaults or descriptions.
sql = "SELECT NULL::text AS nspname,c.relname,a.attname,a.atttypid,a.attnotnull,a.atttypmod,a.attlen,a.attnum,NULL AS adsrc,NULL AS description,NULL AS typbasetype, 'b' AS typtype " +
" FROM pg_class c, pg_attribute a " +
" WHERE a.attrelid=c.oid AND a.attnum > 0 ";
}
 
if (!connection.haveMinimumServerVersion("7.3") && tableNamePattern != null && !"".equals(tableNamePattern))
{
sql += " AND c.relname LIKE '" + escapeQuotes(tableNamePattern) + "' ";
}
if (columnNamePattern != null && !"".equals(columnNamePattern))
{
sql += " AND attname LIKE '" + escapeQuotes(columnNamePattern) + "' ";
}
sql += " ORDER BY nspname,c.relname,attnum ";
 
ResultSet rs = connection.createStatement().executeQuery(sql);
while (rs.next())
{
byte[][] tuple = new byte[numberOfFields][];
int typeOid = (int)rs.getLong("atttypid");
int typeMod = rs.getInt("atttypmod");
 
tuple[0] = null; // Catalog name, not supported
tuple[1] = rs.getBytes("nspname"); // Schema
tuple[2] = rs.getBytes("relname"); // Table name
tuple[3] = rs.getBytes("attname"); // Column name
 
String typtype = rs.getString("typtype");
int sqlType;
if ("c".equals(typtype)) {
sqlType = Types.STRUCT;
} else if ("d".equals(typtype)) {
sqlType = Types.DISTINCT;
} else {
sqlType = connection.getTypeInfo().getSQLType(typeOid);
}
 
tuple[4] = connection.encodeString(Integer.toString(sqlType));
String pgType = connection.getTypeInfo().getPGType(typeOid);
tuple[5] = connection.encodeString(pgType); // Type name
tuple[7] = null; // Buffer length
 
 
String defval = rs.getString("adsrc");
 
if ( defval != null )
{
if ( pgType.equals("int4") )
{
if (defval.indexOf("nextval(") != -1)
tuple[5] = connection.encodeString("serial"); // Type name == serial
}
else if ( pgType.equals("int8") )
{
if (defval.indexOf("nextval(") != -1)
tuple[5] = connection.encodeString("bigserial"); // Type name == bigserial
}
}
 
int decimalDigits = connection.getTypeInfo().getScale(typeOid, typeMod);
int columnSize = connection.getTypeInfo().getPrecision(typeOid, typeMod);
if (columnSize == 0) {
columnSize = connection.getTypeInfo().getDisplaySize(typeOid, typeMod);
}
 
tuple[6] = connection.encodeString(Integer.toString(columnSize));
tuple[8] = connection.encodeString(Integer.toString(decimalDigits));
 
// Everything is base 10 unless we override later.
tuple[9] = connection.encodeString("10");
 
if (pgType.equals("bit") || pgType.equals("varbit"))
{
tuple[9] = connection.encodeString("2");
}
 
tuple[10] = connection.encodeString(Integer.toString(rs.getBoolean("attnotnull") ? java.sql.DatabaseMetaData.columnNoNulls : java.sql.DatabaseMetaData.columnNullable)); // Nullable
tuple[11] = rs.getBytes("description"); // Description (if any)
tuple[12] = rs.getBytes("adsrc"); // Column default
tuple[13] = null; // sql data type (unused)
tuple[14] = null; // sql datetime sub (unused)
tuple[15] = tuple[6]; // char octet length
tuple[16] = rs.getBytes("attnum"); // ordinal position
tuple[17] = connection.encodeString(rs.getBoolean("attnotnull") ? "NO" : "YES"); // Is nullable
 
if (jdbcVersion >= 3) {
int baseTypeOid = (int) rs.getLong("typbasetype");
 
tuple[18] = null; // SCOPE_CATLOG
tuple[19] = null; // SCOPE_SCHEMA
tuple[20] = null; // SCOPE_TABLE
tuple[21] = baseTypeOid == 0 ? null : connection.encodeString(Integer.toString(connection.getTypeInfo().getSQLType(baseTypeOid))); // SOURCE_DATA_TYPE
}
 
if (jdbcVersion >= 4) {
String autoinc = "NO";
if (defval != null && defval.indexOf("nextval(") != -1) {
autoinc = "YES";
}
tuple[22] = connection.encodeString(autoinc);
}
 
v.addElement(tuple);
}
rs.close();
 
return (ResultSet) ((BaseStatement)createMetaDataStatement()).createDriverResultSet(f, v);
}
 
/*
* Get a description of table columns available in a catalog.
*
* <P>Only column descriptions matching the catalog, schema, table
* and column name criteria are returned. They are ordered by
* TABLE_SCHEM, TABLE_NAME and ORDINAL_POSITION.
*
* <P>Each column description has the following columns:
* <OL>
* <LI><B>TABLE_CAT</B> String => table catalog (may be null)
* <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
* <LI><B>TABLE_NAME</B> String => table name
* <LI><B>COLUMN_NAME</B> String => column name
* <LI><B>DATA_TYPE</B> short => SQL type from java.sql.Types
* <LI><B>TYPE_NAME</B> String => Data source dependent type name
* <LI><B>COLUMN_SIZE</B> int => column size. For char or date
* types this is the maximum number of characters, for numeric or
* decimal types this is precision.
* <LI><B>BUFFER_LENGTH</B> is not used.
* <LI><B>DECIMAL_DIGITS</B> int => the number of fractional digits
* <LI><B>NUM_PREC_RADIX</B> int => Radix (typically either 10 or 2)
* <LI><B>NULLABLE</B> int => is NULL allowed?
* <UL>
* <LI> columnNoNulls - might not allow NULL values
* <LI> columnNullable - definitely allows NULL values
* <LI> columnNullableUnknown - nullability unknown
* </UL>
* <LI><B>REMARKS</B> String => comment describing column (may be null)
* <LI><B>COLUMN_DEF</B> String => default value (may be null)
* <LI><B>SQL_DATA_TYPE</B> int => unused
* <LI><B>SQL_DATETIME_SUB</B> int => unused
* <LI><B>CHAR_OCTET_LENGTH</B> int => for char types the
* maximum number of bytes in the column
* <LI><B>ORDINAL_POSITION</B> int => index of column in table
* (starting at 1)
* <LI><B>IS_NULLABLE</B> String => "NO" means column definitely
* does not allow NULL values; "YES" means the column might
* allow NULL values. An empty string means nobody knows.
* </OL>
*
* @param catalog a catalog name; "" retrieves those without a catalog
* @param schemaPattern a schema name pattern; "" retrieves those
* without a schema
* @param tableNamePattern a table name pattern
* @param columnNamePattern a column name pattern
* @return ResultSet each row is a column description
* @see #getSearchStringEscape
*/
public java.sql.ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException
{
return getColumns(2, catalog, schemaPattern, tableNamePattern, columnNamePattern);
}
 
/*
* Get a description of the access rights for a table's columns.
*
* <P>Only privileges matching the column name criteria are
* returned. They are ordered by COLUMN_NAME and PRIVILEGE.
*
* <P>Each privilige description has the following columns:
* <OL>
* <LI><B>TABLE_CAT</B> String => table catalog (may be null)
* <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
* <LI><B>TABLE_NAME</B> String => table name
* <LI><B>COLUMN_NAME</B> String => column name
* <LI><B>GRANTOR</B> => grantor of access (may be null)
* <LI><B>GRANTEE</B> String => grantee of access
* <LI><B>PRIVILEGE</B> String => name of access (SELECT,
* INSERT, UPDATE, REFRENCES, ...)
* <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
* to grant to others; "NO" if not; null if unknown
* </OL>
*
* @param catalog a catalog name; "" retrieves those without a catalog
* @param schema a schema name; "" retrieves those without a schema
* @param table a table name
* @param columnNamePattern a column name pattern
* @return ResultSet each row is a column privilege description
* @see #getSearchStringEscape
*/
public java.sql.ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) throws SQLException
{
Field f[] = new Field[8];
Vector v = new Vector();
 
if (table == null)
table = "%";
 
if (columnNamePattern == null)
columnNamePattern = "%";
 
f[0] = new Field("TABLE_CAT", Oid.VARCHAR);
f[1] = new Field("TABLE_SCHEM", Oid.VARCHAR);
f[2] = new Field("TABLE_NAME", Oid.VARCHAR);
f[3] = new Field("COLUMN_NAME", Oid.VARCHAR);
f[4] = new Field("GRANTOR", Oid.VARCHAR);
f[5] = new Field("GRANTEE", Oid.VARCHAR);
f[6] = new Field("PRIVILEGE", Oid.VARCHAR);
f[7] = new Field("IS_GRANTABLE", Oid.VARCHAR);
 
String sql;
if (connection.haveMinimumServerVersion("7.3"))
{
sql = "SELECT n.nspname,c.relname,u.usename,c.relacl,a.attname " +
" FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c, pg_catalog.pg_user u, pg_catalog.pg_attribute a " +
" WHERE c.relnamespace = n.oid " +
" AND u.usesysid = c.relowner " +
" AND c.oid = a.attrelid " +
" AND c.relkind = 'r' " +
" AND a.attnum > 0 AND NOT a.attisdropped ";
if (schema != null && !"".equals(schema))
{
sql += " AND n.nspname = '" + escapeQuotes(schema) + "' ";
}
}
else
{
sql = "SELECT NULL::text AS nspname,c.relname,u.usename,c.relacl,a.attname " +
"FROM pg_class c, pg_user u,pg_attribute a " +
" WHERE u.usesysid = c.relowner " +
" AND c.oid = a.attrelid " +
" AND a.attnum > 0 " +
" AND c.relkind = 'r' ";
}
 
sql += " AND c.relname = '" + escapeQuotes(table) + "' ";
if (columnNamePattern != null && !"".equals(columnNamePattern))
{
sql += " AND a.attname LIKE '" + escapeQuotes(columnNamePattern) + "' ";
}
sql += " ORDER BY attname ";
 
ResultSet rs = connection.createStatement().executeQuery(sql);
while (rs.next())
{
byte schemaName[] = rs.getBytes("nspname");
byte tableName[] = rs.getBytes("relname");
byte column[] = rs.getBytes("attname");
String owner = rs.getString("usename");
String acl = rs.getString("relacl");
Hashtable permissions = parseACL(acl, owner);
String permNames[] = new String[permissions.size()];
Enumeration e = permissions.keys();
int i = 0;
while (e.hasMoreElements())
{
permNames[i++] = (String)e.nextElement();
}
sortStringArray(permNames);
for (i = 0; i < permNames.length; i++)
{
byte[] privilege = connection.encodeString(permNames[i]);
Vector grantees = (Vector)permissions.get(permNames[i]);
for (int j = 0; j < grantees.size(); j++)
{
String grantee = (String)grantees.elementAt(j);
String grantable = owner.equals(grantee) ? "YES" : "NO";
byte[][] tuple = new byte[8][];
tuple[0] = null;
tuple[1] = schemaName;
tuple[2] = tableName;
tuple[3] = column;
tuple[4] = connection.encodeString(owner);
tuple[5] = connection.encodeString(grantee);
tuple[6] = privilege;
tuple[7] = connection.encodeString(grantable);
v.addElement(tuple);
}
}
}
rs.close();
 
return (ResultSet) ((BaseStatement)createMetaDataStatement()).createDriverResultSet(f, v);
}
 
/*
* Get a description of the access rights for each table available
* in a catalog.
*
* This method is currently unimplemented.
*
* <P>Only privileges matching the schema and table name
* criteria are returned. They are ordered by TABLE_SCHEM,
* TABLE_NAME, and PRIVILEGE.
*
* <P>Each privilige description has the following columns:
* <OL>
* <LI><B>TABLE_CAT</B> String => table catalog (may be null)
* <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
* <LI><B>TABLE_NAME</B> String => table name
* <LI><B>GRANTOR</B> => grantor of access (may be null)
* <LI><B>GRANTEE</B> String => grantee of access
* <LI><B>PRIVILEGE</B> String => name of access (SELECT,
* INSERT, UPDATE, REFRENCES, ...)
* <LI><B>IS_GRANTABLE</B> String => "YES" if grantee is permitted
* to grant to others; "NO" if not; null if unknown
* </OL>
*
* @param catalog a catalog name; "" retrieves those without a catalog
* @param schemaPattern a schema name pattern; "" retrieves those
* without a schema
* @param tableNamePattern a table name pattern
* @return ResultSet each row is a table privilege description
* @see #getSearchStringEscape
*/
public java.sql.ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) throws SQLException
{
Field f[] = new Field[7];
Vector v = new Vector();
 
f[0] = new Field("TABLE_CAT", Oid.VARCHAR);
f[1] = new Field("TABLE_SCHEM", Oid.VARCHAR);
f[2] = new Field("TABLE_NAME", Oid.VARCHAR);
f[3] = new Field("GRANTOR", Oid.VARCHAR);
f[4] = new Field("GRANTEE", Oid.VARCHAR);
f[5] = new Field("PRIVILEGE", Oid.VARCHAR);
f[6] = new Field("IS_GRANTABLE", Oid.VARCHAR);
 
String sql;
if (connection.haveMinimumServerVersion("7.3"))
{
sql = "SELECT n.nspname,c.relname,u.usename,c.relacl " +
" FROM pg_catalog.pg_namespace n, pg_catalog.pg_class c, pg_catalog.pg_user u " +
" WHERE c.relnamespace = n.oid " +
" AND u.usesysid = c.relowner " +
" AND c.relkind = 'r' ";
if (schemaPattern != null && !"".equals(schemaPattern))
{
sql += " AND n.nspname LIKE '" + escapeQuotes(schemaPattern) + "' ";
}
}
else
{
sql = "SELECT NULL::text AS nspname,c.relname,u.usename,c.relacl " +
"FROM pg_class c, pg_user u " +
" WHERE u.usesysid = c.relowner " +
" AND c.relkind = 'r' ";
}
 
if (tableNamePattern != null && !"".equals(tableNamePattern))
{
sql += " AND c.relname LIKE '" + escapeQuotes(tableNamePattern) + "' ";
}
sql += " ORDER BY nspname, relname ";
 
ResultSet rs = connection.createStatement().executeQuery(sql);
while (rs.next())
{
byte schema[] = rs.getBytes("nspname");
byte table[] = rs.getBytes("relname");
String owner = rs.getString("usename");
String acl = rs.getString("relacl");
Hashtable permissions = parseACL(acl, owner);
String permNames[] = new String[permissions.size()];
Enumeration e = permissions.keys();
int i = 0;
while (e.hasMoreElements())
{
permNames[i++] = (String)e.nextElement();
}
sortStringArray(permNames);
for (i = 0; i < permNames.length; i++)
{
byte[] privilege = connection.encodeString(permNames[i]);
Vector grantees = (Vector)permissions.get(permNames[i]);
for (int j = 0; j < grantees.size(); j++)
{
String grantee = (String)grantees.elementAt(j);
String grantable = owner.equals(grantee) ? "YES" : "NO";
byte[][] tuple = new byte[7][];
tuple[0] = null;
tuple[1] = schema;
tuple[2] = table;
tuple[3] = connection.encodeString(owner);
tuple[4] = connection.encodeString(grantee);
tuple[5] = privilege;
tuple[6] = connection.encodeString(grantable);
v.addElement(tuple);
}
}
}
rs.close();
 
return (ResultSet) ((BaseStatement)createMetaDataStatement()).createDriverResultSet(f, v);
}
 
private static void sortStringArray(String s[]) {
for (int i = 0; i < s.length - 1; i++)
{
for (int j = i + 1; j < s.length; j++)
{
if (s[i].compareTo(s[j]) > 0)
{
String tmp = s[i];
s[i] = s[j];
s[j] = tmp;
}
}
}
}
 
/**
* Parse an String of ACLs into a Vector of ACLs.
*/
private static Vector parseACLArray(String aclString) {
Vector acls = new Vector();
if (aclString == null || aclString.length() == 0)
{
return acls;
}
boolean inQuotes = false;
// start at 1 because of leading "{"
int beginIndex = 1;
char prevChar = ' ';
for (int i = beginIndex; i < aclString.length(); i++)
{
 
char c = aclString.charAt(i);
if (c == '"' && prevChar != '\\')
{
inQuotes = !inQuotes;
}
else if (c == ',' && !inQuotes)
{
acls.addElement(aclString.substring(beginIndex, i));
beginIndex = i + 1;
}
prevChar = c;
}
// add last element removing the trailing "}"
acls.addElement(aclString.substring(beginIndex, aclString.length() - 1));
 
// Strip out enclosing quotes, if any.
for (int i = 0; i < acls.size(); i++)
{
String acl = (String)acls.elementAt(i);
if (acl.startsWith("\"") && acl.endsWith("\""))
{
acl = acl.substring(1, acl.length() - 1);
acls.setElementAt(acl, i);
}
}
return acls;
}
 
/**
* Add the user described by the given acl to the Vectors of users
* with the privileges described by the acl.
*/
private void addACLPrivileges(String acl, Hashtable privileges) {
int equalIndex = acl.lastIndexOf("=");
String name = acl.substring(0, equalIndex);
if (name.length() == 0)
{
name = "PUBLIC";
}
String privs = acl.substring(equalIndex + 1);
for (int i = 0; i < privs.length(); i++)
{
char c = privs.charAt(i);
String sqlpriv;
switch (c)
{
case 'a':
sqlpriv = "INSERT";
break;
case 'r':
sqlpriv = "SELECT";
break;
case 'w':
sqlpriv = "UPDATE";
break;
case 'd':
sqlpriv = "DELETE";
break;
case 'D':
sqlpriv = "TRUNCATE";
break;
case 'R':
sqlpriv = "RULE";
break;
case 'x':
sqlpriv = "REFERENCES";
break;
case 't':
sqlpriv = "TRIGGER";
break;
// the following can't be granted to a table, but
// we'll keep them for completeness.
case 'X':
sqlpriv = "EXECUTE";
break;
case 'U':
sqlpriv = "USAGE";
break;
case 'C':
sqlpriv = "CREATE";
break;
case 'T':
sqlpriv = "CREATE TEMP";
break;
default:
sqlpriv = "UNKNOWN";
}
Vector usersWithPermission = (Vector)privileges.get(sqlpriv);
if (usersWithPermission == null)
{
usersWithPermission = new Vector();
privileges.put(sqlpriv, usersWithPermission);
}
usersWithPermission.addElement(name);
}
}
 
/**
* Take the a String representing an array of ACLs and return
* a Hashtable mapping the SQL permission name to a Vector of
* usernames who have that permission.
*/
protected Hashtable parseACL(String aclArray, String owner) {
if (aclArray == null)
{
//null acl is a shortcut for owner having full privs
aclArray = "{" + owner + "=arwdRxt}";
}
Vector acls = parseACLArray(aclArray);
Hashtable privileges = new Hashtable();
for (int i = 0; i < acls.size(); i++)
{
String acl = (String)acls.elementAt(i);
addACLPrivileges(acl, privileges);
}
return privileges;
}
 
/*
* Get a description of a table's optimal set of columns that
* uniquely identifies a row. They are ordered by SCOPE.
*
* <P>Each column description has the following columns:
* <OL>
* <LI><B>SCOPE</B> short => actual scope of result
* <UL>
* <LI> bestRowTemporary - very temporary, while using row
* <LI> bestRowTransaction - valid for remainder of current transaction
* <LI> bestRowSession - valid for remainder of current session
* </UL>
* <LI><B>COLUMN_NAME</B> String => column name
* <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types
* <LI><B>TYPE_NAME</B> String => Data source dependent type name
* <LI><B>COLUMN_SIZE</B> int => precision
* <LI><B>BUFFER_LENGTH</B> int => not used
* <LI><B>DECIMAL_DIGITS</B> short => scale
* <LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column
* like an Oracle ROWID
* <UL>
* <LI> bestRowUnknown - may or may not be pseudo column
* <LI> bestRowNotPseudo - is NOT a pseudo column
* <LI> bestRowPseudo - is a pseudo column
* </UL>
* </OL>
*
* @param catalog a catalog name; "" retrieves those without a catalog
* @param schema a schema name; "" retrieves those without a schema
* @param table a table name
* @param scope the scope of interest; use same values as SCOPE
* @param nullable include columns that are nullable?
* @return ResultSet each row is a column description
*/
// Implementation note: This is required for Borland's JBuilder to work
public java.sql.ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) throws SQLException
{
Field f[] = new Field[8];
Vector v = new Vector(); // The new ResultSet tuple stuff
 
f[0] = new Field("SCOPE", Oid.INT2);
f[1] = new Field("COLUMN_NAME", Oid.VARCHAR);
f[2] = new Field("DATA_TYPE", Oid.INT2);
f[3] = new Field("TYPE_NAME", Oid.VARCHAR);
f[4] = new Field("COLUMN_SIZE", Oid.INT4);
f[5] = new Field("BUFFER_LENGTH", Oid.INT4);
f[6] = new Field("DECIMAL_DIGITS", Oid.INT2);
f[7] = new Field("PSEUDO_COLUMN", Oid.INT2);
 
/* At the moment this simply returns a table's primary key,
* if there is one. I believe other unique indexes, ctid,
* and oid should also be considered. -KJ
*/
 
String sql;
if (connection.haveMinimumServerVersion("8.1"))
{
sql = "SELECT a.attname, a.atttypid, atttypmod "
+ "FROM pg_catalog.pg_class ct "
+ " JOIN pg_catalog.pg_attribute a ON (ct.oid = a.attrelid) "
+ " JOIN pg_catalog.pg_namespace n ON (ct.relnamespace = n.oid) "
+ " JOIN (SELECT i.indexrelid, i.indrelid, i.indisprimary, "
+ " information_schema._pg_expandarray(i.indkey) AS keys "
+ " FROM pg_catalog.pg_index i) i "
+ " ON (a.attnum = (i.keys).x AND a.attrelid = i.indrelid) "
+ "WHERE true ";
if (schema != null && !"".equals(schema))
{
sql += " AND n.nspname = '" + escapeQuotes(schema) + "' ";
}
}
else
{
String from;
String where = "";
if (connection.haveMinimumServerVersion("7.3"))
{
from = " FROM pg_catalog.pg_namespace n, pg_catalog.pg_class ct, pg_catalog.pg_class ci, pg_catalog.pg_attribute a, pg_catalog.pg_index i ";
where = " AND ct.relnamespace = n.oid ";
if (schema != null && !"".equals(schema))
{
where += " AND n.nspname = '" + escapeQuotes(schema) + "' ";
}
}
else
{
from = " FROM pg_class ct, pg_class ci, pg_attribute a, pg_index i ";
}
sql = "SELECT a.attname, a.atttypid, a.atttypmod " +
from +
" WHERE ct.oid=i.indrelid AND ci.oid=i.indexrelid " +
" AND a.attrelid=ci.oid " +
where;
}
 
sql += " AND ct.relname = '" + escapeQuotes(table) + "' " +
" AND i.indisprimary " +
" ORDER BY a.attnum ";
 
ResultSet rs = connection.createStatement().executeQuery(sql);
while (rs.next())
{
byte tuple[][] = new byte[8][];
int typeOid = (int)rs.getLong("atttypid");
int typeMod = rs.getInt("atttypmod");
int decimalDigits = connection.getTypeInfo().getScale(typeOid, typeMod);
int columnSize = connection.getTypeInfo().getPrecision(typeOid, typeMod);
if (columnSize == 0) {
columnSize = connection.getTypeInfo().getDisplaySize(typeOid, typeMod);
}
tuple[0] = connection.encodeString(Integer.toString(scope));
tuple[1] = rs.getBytes("attname");
tuple[2] = connection.encodeString(Integer.toString(connection.getTypeInfo().getSQLType(typeOid)));
tuple[3] = connection.encodeString(connection.getTypeInfo().getPGType(typeOid));
tuple[4] = connection.encodeString(Integer.toString(columnSize));
tuple[5] = null; // unused
tuple[6] = connection.encodeString(Integer.toString(decimalDigits));
tuple[7] = connection.encodeString(Integer.toString(java.sql.DatabaseMetaData.bestRowNotPseudo));
v.addElement(tuple);
}
 
return (ResultSet) ((BaseStatement)createMetaDataStatement()).createDriverResultSet(f, v);
}
 
/*
* Get a description of a table's columns that are automatically
* updated when any value in a row is updated. They are
* unordered.
*
* <P>Each column description has the following columns:
* <OL>
* <LI><B>SCOPE</B> short => is not used
* <LI><B>COLUMN_NAME</B> String => column name
* <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types
* <LI><B>TYPE_NAME</B> String => Data source dependent type name
* <LI><B>COLUMN_SIZE</B> int => precision
* <LI><B>BUFFER_LENGTH</B> int => length of column value in bytes
* <LI><B>DECIMAL_DIGITS</B> short => scale
* <LI><B>PSEUDO_COLUMN</B> short => is this a pseudo column
* like an Oracle ROWID
* <UL>
* <LI> versionColumnUnknown - may or may not be pseudo column
* <LI> versionColumnNotPseudo - is NOT a pseudo column
* <LI> versionColumnPseudo - is a pseudo column
* </UL>
* </OL>
*
* @param catalog a catalog name; "" retrieves those without a catalog
* @param schema a schema name; "" retrieves those without a schema
* @param table a table name
* @return ResultSet each row is a column description
*/
public java.sql.ResultSet getVersionColumns(String catalog, String schema, String table) throws SQLException
{
Field f[] = new Field[8];
Vector v = new Vector(); // The new ResultSet tuple stuff
 
f[0] = new Field("SCOPE", Oid.INT2);
f[1] = new Field("COLUMN_NAME", Oid.VARCHAR);
f[2] = new Field("DATA_TYPE", Oid.INT2);
f[3] = new Field("TYPE_NAME", Oid.VARCHAR);
f[4] = new Field("COLUMN_SIZE", Oid.INT4);
f[5] = new Field("BUFFER_LENGTH", Oid.INT4);
f[6] = new Field("DECIMAL_DIGITS", Oid.INT2);
f[7] = new Field("PSEUDO_COLUMN", Oid.INT2);
 
byte tuple[][] = new byte[8][];
 
/* Postgresql does not have any column types that are
* automatically updated like some databases' timestamp type.
* We can't tell what rules or triggers might be doing, so we
* are left with the system columns that change on an update.
* An update may change all of the following system columns:
* ctid, xmax, xmin, cmax, and cmin. Depending on if we are
* in a transaction and wether we roll it back or not the
* only guaranteed change is to ctid. -KJ
*/
 
tuple[0] = null;
tuple[1] = connection.encodeString("ctid");
tuple[2] = connection.encodeString(Integer.toString(connection.getTypeInfo().getSQLType("tid")));
tuple[3] = connection.encodeString("tid");
tuple[4] = null;
tuple[5] = null;
tuple[6] = null;
tuple[7] = connection.encodeString(Integer.toString(java.sql.DatabaseMetaData.versionColumnPseudo));
v.addElement(tuple);
 
/* Perhaps we should check that the given
* catalog.schema.table actually exists. -KJ
*/
return (ResultSet) ((BaseStatement)createMetaDataStatement()).createDriverResultSet(f, v);
}
 
/*
* Get a description of a table's primary key columns. They
* are ordered by COLUMN_NAME.
*
* <P>Each column description has the following columns:
* <OL>
* <LI><B>TABLE_CAT</B> String => table catalog (may be null)
* <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
* <LI><B>TABLE_NAME</B> String => table name
* <LI><B>COLUMN_NAME</B> String => column name
* <LI><B>KEY_SEQ</B> short => sequence number within primary key
* <LI><B>PK_NAME</B> String => primary key name (may be null)
* </OL>
*
* @param catalog a catalog name; "" retrieves those without a catalog
* @param schema a schema name pattern; "" retrieves those
* without a schema
* @param table a table name
* @return ResultSet each row is a primary key column description
*/
public java.sql.ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException
{
String sql;
if (connection.haveMinimumServerVersion("8.1"))
{
sql = "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, "
+ " ct.relname AS TABLE_NAME, a.attname AS COLUMN_NAME, "
+ " (i.keys).n AS KEY_SEQ, ci.relname AS PK_NAME "
+ "FROM pg_catalog.pg_class ct "
+ " JOIN pg_catalog.pg_attribute a ON (ct.oid = a.attrelid) "
+ " JOIN pg_catalog.pg_namespace n ON (ct.relnamespace = n.oid) "
+ " JOIN (SELECT i.indexrelid, i.indrelid, i.indisprimary, "
+ " information_schema._pg_expandarray(i.indkey) AS keys "
+ " FROM pg_catalog.pg_index i) i "
+ " ON (a.attnum = (i.keys).x AND a.attrelid = i.indrelid) "
+ " JOIN pg_catalog.pg_class ci ON (ci.oid = i.indexrelid) "
+ "WHERE true ";
if (schema != null && !"".equals(schema))
{
sql += " AND n.nspname = '" + escapeQuotes(schema) + "' ";
}
} else {
String select;
String from;
String where = "";
 
if (connection.haveMinimumServerVersion("7.3"))
{
select = "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, ";
from = " FROM pg_catalog.pg_namespace n, pg_catalog.pg_class ct, pg_catalog.pg_class ci, pg_catalog.pg_attribute a, pg_catalog.pg_index i ";
where = " AND ct.relnamespace = n.oid ";
if (schema != null && !"".equals(schema))
{
where += " AND n.nspname = '" + escapeQuotes(schema) + "' ";
}
}
else
{
select = "SELECT NULL AS TABLE_CAT, NULL AS TABLE_SCHEM, ";
from = " FROM pg_class ct, pg_class ci, pg_attribute a, pg_index i ";
}
 
sql = select +
" ct.relname AS TABLE_NAME, " +
" a.attname AS COLUMN_NAME, " +
" a.attnum AS KEY_SEQ, " +
" ci.relname AS PK_NAME " +
from +
" WHERE ct.oid=i.indrelid AND ci.oid=i.indexrelid " +
" AND a.attrelid=ci.oid " +
where;
}
 
if (table != null && !"".equals(table))
{
sql += " AND ct.relname = '" + escapeQuotes(table) + "' ";
}
 
sql += " AND i.indisprimary " +
" ORDER BY table_name, pk_name, key_seq";
 
return createMetaDataStatement().executeQuery(sql);
}
 
/**
*
* @param primaryCatalog
* @param primarySchema
* @param primaryTable if provided will get the keys exported by this table
* @param foreignTable if provided will get the keys imported by this table
* @return ResultSet
* @throws SQLException
*/
 
protected java.sql.ResultSet getImportedExportedKeys(String primaryCatalog, String primarySchema, String primaryTable, String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException
{
Field f[] = new Field[14];
 
f[0] = new Field("PKTABLE_CAT", Oid.VARCHAR);
f[1] = new Field("PKTABLE_SCHEM", Oid.VARCHAR);
f[2] = new Field("PKTABLE_NAME", Oid.VARCHAR);
f[3] = new Field("PKCOLUMN_NAME", Oid.VARCHAR);
f[4] = new Field("FKTABLE_CAT", Oid.VARCHAR);
f[5] = new Field("FKTABLE_SCHEM", Oid.VARCHAR);
f[6] = new Field("FKTABLE_NAME", Oid.VARCHAR);
f[7] = new Field("FKCOLUMN_NAME", Oid.VARCHAR);
f[8] = new Field("KEY_SEQ", Oid.INT2);
f[9] = new Field("UPDATE_RULE", Oid.INT2);
f[10] = new Field("DELETE_RULE", Oid.INT2);
f[11] = new Field("FK_NAME", Oid.VARCHAR);
f[12] = new Field("PK_NAME", Oid.VARCHAR);
f[13] = new Field("DEFERRABILITY", Oid.INT2);
 
 
String select;
String from;
String where = "";
 
/*
* The addition of the pg_constraint in 7.3 table should have really
* helped us out here, but it comes up just a bit short.
* - The conkey, confkey columns aren't really useful without
* contrib/array unless we want to issues separate queries.
* - Unique indexes that can support foreign keys are not necessarily
* added to pg_constraint. Also multiple unique indexes covering
* the same keys can be created which make it difficult to determine
* the PK_NAME field.
*/
 
if (connection.haveMinimumServerVersion("7.4"))
{
String sql = "SELECT NULL::text AS PKTABLE_CAT, pkn.nspname AS PKTABLE_SCHEM, pkc.relname AS PKTABLE_NAME, pka.attname AS PKCOLUMN_NAME, " +
"NULL::text AS FKTABLE_CAT, fkn.nspname AS FKTABLE_SCHEM, fkc.relname AS FKTABLE_NAME, fka.attname AS FKCOLUMN_NAME, " +
"pos.n AS KEY_SEQ, " +
"CASE con.confupdtype " +
" WHEN 'c' THEN " + DatabaseMetaData.importedKeyCascade +
" WHEN 'n' THEN " + DatabaseMetaData.importedKeySetNull +
" WHEN 'd' THEN " + DatabaseMetaData.importedKeySetDefault +
" WHEN 'r' THEN " + DatabaseMetaData.importedKeyRestrict +
" WHEN 'a' THEN " + DatabaseMetaData.importedKeyNoAction +
" ELSE NULL END AS UPDATE_RULE, " +
"CASE con.confdeltype " +
" WHEN 'c' THEN " + DatabaseMetaData.importedKeyCascade +
" WHEN 'n' THEN " + DatabaseMetaData.importedKeySetNull +
" WHEN 'd' THEN " + DatabaseMetaData.importedKeySetDefault +
" WHEN 'r' THEN " + DatabaseMetaData.importedKeyRestrict +
" WHEN 'a' THEN " + DatabaseMetaData.importedKeyNoAction +
" ELSE NULL END AS DELETE_RULE, " +
"con.conname AS FK_NAME, pkic.relname AS PK_NAME, " +
"CASE " +
" WHEN con.condeferrable AND con.condeferred THEN " + DatabaseMetaData.importedKeyInitiallyDeferred +
" WHEN con.condeferrable THEN " + DatabaseMetaData.importedKeyInitiallyImmediate +
" ELSE " + DatabaseMetaData.importedKeyNotDeferrable +
" END AS DEFERRABILITY " +
" FROM " +
" pg_catalog.pg_namespace pkn, pg_catalog.pg_class pkc, pg_catalog.pg_attribute pka, " +
" pg_catalog.pg_namespace fkn, pg_catalog.pg_class fkc, pg_catalog.pg_attribute fka, " +
" pg_catalog.pg_constraint con, ";
if (connection.haveMinimumServerVersion("8.0")) {
sql += " pg_catalog.generate_series(1, " + getMaxIndexKeys() + ") pos(n), ";
} else {
sql += " information_schema._pg_keypositions() pos(n), ";
}
sql += " pg_catalog.pg_depend dep, pg_catalog.pg_class pkic " +
" WHERE pkn.oid = pkc.relnamespace AND pkc.oid = pka.attrelid AND pka.attnum = con.confkey[pos.n] AND con.confrelid = pkc.oid " +
" AND fkn.oid = fkc.relnamespace AND fkc.oid = fka.attrelid AND fka.attnum = con.conkey[pos.n] AND con.conrelid = fkc.oid " +
" AND con.contype = 'f' AND con.oid = dep.objid AND pkic.oid = dep.refobjid AND pkic.relkind = 'i' AND dep.classid = 'pg_constraint'::regclass::oid AND dep.refclassid = 'pg_class'::regclass::oid ";
if (primarySchema != null && !"".equals(primarySchema))
{
sql += " AND pkn.nspname = '" + escapeQuotes(primarySchema) + "' ";
}
if (foreignSchema != null && !"".equals(foreignSchema))
{
sql += " AND fkn.nspname = '" + escapeQuotes(foreignSchema) + "' ";
}
if (primaryTable != null && !"".equals(primaryTable))
{
sql += " AND pkc.relname = '" + escapeQuotes(primaryTable) + "' ";
}
if (foreignTable != null && !"".equals(foreignTable))
{
sql += " AND fkc.relname = '" + escapeQuotes(foreignTable) + "' ";
}
 
if (primaryTable != null)
{
// ILM : con.conname required otherwise we cannot assemble
// multi-field foreign keys when a table has multiple links
// to another
sql += " ORDER BY fkn.nspname,fkc.relname,con.conname,pos.n";
}
else
{
// ILM
sql += " ORDER BY pkn.nspname,pkc.relname,con.conname,pos.n";
}
 
return createMetaDataStatement().executeQuery(sql);
}
else if (connection.haveMinimumServerVersion("7.3"))
{
select = "SELECT DISTINCT n1.nspname as pnspname,n2.nspname as fnspname, ";
from = " FROM pg_catalog.pg_namespace n1 " +
" JOIN pg_catalog.pg_class c1 ON (c1.relnamespace = n1.oid) " +
" JOIN pg_catalog.pg_index i ON (c1.oid=i.indrelid) " +
" JOIN pg_catalog.pg_class ic ON (i.indexrelid=ic.oid) " +
" JOIN pg_catalog.pg_attribute a ON (ic.oid=a.attrelid), " +
" pg_catalog.pg_namespace n2 " +
" JOIN pg_catalog.pg_class c2 ON (c2.relnamespace=n2.oid), " +
" pg_catalog.pg_trigger t1 " +
" JOIN pg_catalog.pg_proc p1 ON (t1.tgfoid=p1.oid), " +
" pg_catalog.pg_trigger t2 " +
" JOIN pg_catalog.pg_proc p2 ON (t2.tgfoid=p2.oid) ";
if (primarySchema != null && !"".equals(primarySchema))
{
where += " AND n1.nspname = '" + escapeQuotes(primarySchema) + "' ";
}
if (foreignSchema != null && !"".equals(foreignSchema))
{
where += " AND n2.nspname = '" + escapeQuotes(foreignSchema) + "' ";
}
}
else
{
select = "SELECT DISTINCT NULL::text as pnspname, NULL::text as fnspname, ";
from = " FROM pg_class c1 " +
" JOIN pg_index i ON (c1.oid=i.indrelid) " +
" JOIN pg_class ic ON (i.indexrelid=ic.oid) " +
" JOIN pg_attribute a ON (ic.oid=a.attrelid), " +
" pg_class c2, " +
" pg_trigger t1 " +
" JOIN pg_proc p1 ON (t1.tgfoid=p1.oid), " +
" pg_trigger t2 " +
" JOIN pg_proc p2 ON (t2.tgfoid=p2.oid) ";
}
 
String sql = select
+ "c1.relname as prelname, "
+ "c2.relname as frelname, "
+ "t1.tgconstrname, "
+ "a.attnum as keyseq, "
+ "ic.relname as fkeyname, "
+ "t1.tgdeferrable, "
+ "t1.tginitdeferred, "
+ "t1.tgnargs,t1.tgargs, "
+ "p1.proname as updaterule, "
+ "p2.proname as deleterule "
+ from
+ "WHERE "
// isolate the update rule
+ "(t1.tgrelid=c1.oid "
+ "AND t1.tgisconstraint "
+ "AND t1.tgconstrrelid=c2.oid "
+ "AND p1.proname ~ '^RI_FKey_.*_upd$') "
 
+ "AND "
// isolate the delete rule
+ "(t2.tgrelid=c1.oid "
+ "AND t2.tgisconstraint "
+ "AND t2.tgconstrrelid=c2.oid "
+ "AND p2.proname ~ '^RI_FKey_.*_del$') "
 
+ "AND i.indisprimary "
+ where;
 
if (primaryTable != null)
{
sql += "AND c1.relname='" + escapeQuotes(primaryTable) + "' ";
}
if (foreignTable != null)
{
sql += "AND c2.relname='" + escapeQuotes(foreignTable) + "' ";
}
 
sql += "ORDER BY ";
 
// orderby is as follows getExported, orders by FKTABLE,
// getImported orders by PKTABLE
// getCrossReference orders by FKTABLE, so this should work for both,
// since when getting crossreference, primaryTable will be defined
 
if (primaryTable != null)
{
if (connection.haveMinimumServerVersion("7.3"))
{
sql += "fnspname,";
}
sql += "frelname";
}
else
{
if (connection.haveMinimumServerVersion("7.3"))
{
sql += "pnspname,";
}
sql += "prelname";
}
 
sql += ",keyseq";
 
ResultSet rs = connection.createStatement().executeQuery(sql);
 
// returns the following columns
// and some example data with a table defined as follows
 
// create table people ( id int primary key);
// create table policy ( id int primary key);
// create table users ( id int primary key, people_id int references people(id), policy_id int references policy(id))
 
// prelname | frelname | tgconstrname | keyseq | fkeyName | tgdeferrable | tginitdeferred
// 1 | 2 | 3 | 4 | 5 | 6 | 7
 
// people | users | <unnamed> | 1 | people_pkey | f | f
 
// | tgnargs | tgargs | updaterule | deleterule
// | 8 | 9 | 10 | 11
// | 6 | <unnamed>\000users\000people\000UNSPECIFIED\000people_id\000id\000 | RI_FKey_noaction_upd | RI_FKey_noaction_del
 
Vector tuples = new Vector();
 
while ( rs.next() )
{
byte tuple[][] = new byte[14][];
 
tuple[1] = rs.getBytes(1); //PKTABLE_SCHEM
tuple[5] = rs.getBytes(2); //FKTABLE_SCHEM
tuple[2] = rs.getBytes(3); //PKTABLE_NAME
tuple[6] = rs.getBytes(4); //FKTABLE_NAME
String fKeyName = rs.getString(5);
String updateRule = rs.getString(12);
 
if (updateRule != null )
{
// Rules look like this RI_FKey_noaction_del so we want to pull out the part between the 'Key_' and the last '_' s
 
String rule = updateRule.substring(8, updateRule.length() - 4);
 
int action = java.sql.DatabaseMetaData.importedKeyNoAction;
 
if ( rule == null || "noaction".equals(rule) )
action = java.sql.DatabaseMetaData.importedKeyNoAction;
if ("cascade".equals(rule))
action = java.sql.DatabaseMetaData.importedKeyCascade;
else if ("setnull".equals(rule))
action = java.sql.DatabaseMetaData.importedKeySetNull;
else if ("setdefault".equals(rule))
action = java.sql.DatabaseMetaData.importedKeySetDefault;
else if ("restrict".equals(rule))
action = java.sql.DatabaseMetaData.importedKeyRestrict;
 
tuple[9] = connection.encodeString(Integer.toString(action));
 
}
 
String deleteRule = rs.getString(13);
 
if ( deleteRule != null )
{
 
String rule = deleteRule.substring(8, deleteRule.length() - 4);
 
int action = java.sql.DatabaseMetaData.importedKeyNoAction;
if ("cascade".equals(rule))
action = java.sql.DatabaseMetaData.importedKeyCascade;
else if ("setnull".equals(rule))
action = java.sql.DatabaseMetaData.importedKeySetNull;
else if ("setdefault".equals(rule))
action = java.sql.DatabaseMetaData.importedKeySetDefault;
else if ("restrict".equals(rule))
action = java.sql.DatabaseMetaData.importedKeyRestrict;
tuple[10] = connection.encodeString(Integer.toString(action));
}
 
 
int keySequence = rs.getInt(6); //KEY_SEQ
 
// Parse the tgargs data
String fkeyColumn = "";
String pkeyColumn = "";
String fkName = "";
// Note, I am guessing at most of this, but it should be close
// if not, please correct
// the keys are in pairs and start after the first four arguments
// the arguments are seperated by \000
 
String targs = rs.getString(11);
 
// args look like this
//<unnamed>\000ww\000vv\000UNSPECIFIED\000m\000a\000n\000b\000
// we are primarily interested in the column names which are the last items in the string
 
Vector tokens = tokenize(targs, "\\000");
if (tokens.size() > 0)
{
fkName = (String)tokens.elementAt(0);
}
 
if (fkName.startsWith("<unnamed>"))
{
fkName = targs;
}
 
int element = 4 + (keySequence - 1) * 2;
if (tokens.size() > element)
{
fkeyColumn = (String)tokens.elementAt(element);
}
 
element++;
if (tokens.size() > element)
{
pkeyColumn = (String)tokens.elementAt(element);
}
 
tuple[3] = connection.encodeString(pkeyColumn); //PKCOLUMN_NAME
tuple[7] = connection.encodeString(fkeyColumn); //FKCOLUMN_NAME
 
tuple[8] = rs.getBytes(6); //KEY_SEQ
tuple[11] = connection.encodeString(fkName); //FK_NAME this will give us a unique name for the foreign key
tuple[12] = rs.getBytes(7); //PK_NAME
 
// DEFERRABILITY
int deferrability = java.sql.DatabaseMetaData.importedKeyNotDeferrable;
boolean deferrable = rs.getBoolean(8);
boolean initiallyDeferred = rs.getBoolean(9);
if (deferrable)
{
if (initiallyDeferred)
deferrability = java.sql.DatabaseMetaData.importedKeyInitiallyDeferred;
else
deferrability = java.sql.DatabaseMetaData.importedKeyInitiallyImmediate;
}
tuple[13] = connection.encodeString(Integer.toString(deferrability));
 
tuples.addElement(tuple);
}
 
return (ResultSet) ((BaseStatement)createMetaDataStatement()).createDriverResultSet(f, tuples);
}
 
/*
* Get a description of the primary key columns that are
* referenced by a table's foreign key columns (the primary keys
* imported by a table). They are ordered by PKTABLE_CAT,
* PKTABLE_SCHEM, PKTABLE_NAME, and KEY_SEQ.
*
* <P>Each primary key column description has the following columns:
* <OL>
* <LI><B>PKTABLE_CAT</B> String => primary key table catalog
* being imported (may be null)
* <LI><B>PKTABLE_SCHEM</B> String => primary key table schema
* being imported (may be null)
* <LI><B>PKTABLE_NAME</B> String => primary key table name
* being imported
* <LI><B>PKCOLUMN_NAME</B> String => primary key column name
* being imported
* <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
* <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
* <LI><B>FKTABLE_NAME</B> String => foreign key table name
* <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
* <LI><B>KEY_SEQ</B> short => sequence number within foreign key
* <LI><B>UPDATE_RULE</B> short => What happens to
* foreign key when primary is updated:
* <UL>
* <LI> importedKeyCascade - change imported key to agree
* with primary key update
* <LI> importedKeyRestrict - do not allow update of primary
* key if it has been imported
* <LI> importedKeySetNull - change imported key to NULL if
* its primary key has been updated
* </UL>
* <LI><B>DELETE_RULE</B> short => What happens to
* the foreign key when primary is deleted.
* <UL>
* <LI> importedKeyCascade - delete rows that import a deleted key
* <LI> importedKeyRestrict - do not allow delete of primary
* key if it has been imported
* <LI> importedKeySetNull - change imported key to NULL if
* its primary key has been deleted
* </UL>
* <LI><B>FK_NAME</B> String => foreign key name (may be null)
* <LI><B>PK_NAME</B> String => primary key name (may be null)
* </OL>
*
* @param catalog a catalog name; "" retrieves those without a catalog
* @param schema a schema name pattern; "" retrieves those
* without a schema
* @param table a table name
* @return ResultSet each row is a primary key column description
* @see #getExportedKeys
*/
public java.sql.ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException
{
return getImportedExportedKeys(null, null, null, catalog, schema, table);
}
 
/*
* Get a description of a foreign key columns that reference a
* table's primary key columns (the foreign keys exported by a
* table). They are ordered by FKTABLE_CAT, FKTABLE_SCHEM,
* FKTABLE_NAME, and KEY_SEQ.
*
* This method is currently unimplemented.
*
* <P>Each foreign key column description has the following columns:
* <OL>
* <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)
* <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)
* <LI><B>PKTABLE_NAME</B> String => primary key table name
* <LI><B>PKCOLUMN_NAME</B> String => primary key column name
* <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
* being exported (may be null)
* <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
* being exported (may be null)
* <LI><B>FKTABLE_NAME</B> String => foreign key table name
* being exported
* <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
* being exported
* <LI><B>KEY_SEQ</B> short => sequence number within foreign key
* <LI><B>UPDATE_RULE</B> short => What happens to
* foreign key when primary is updated:
* <UL>
* <LI> importedKeyCascade - change imported key to agree
* with primary key update
* <LI> importedKeyRestrict - do not allow update of primary
* key if it has been imported
* <LI> importedKeySetNull - change imported key to NULL if
* its primary key has been updated
* </UL>
* <LI><B>DELETE_RULE</B> short => What happens to
* the foreign key when primary is deleted.
* <UL>
* <LI> importedKeyCascade - delete rows that import a deleted key
* <LI> importedKeyRestrict - do not allow delete of primary
* key if it has been imported
* <LI> importedKeySetNull - change imported key to NULL if
* its primary key has been deleted
* </UL>
* <LI><B>FK_NAME</B> String => foreign key identifier (may be null)
* <LI><B>PK_NAME</B> String => primary key identifier (may be null)
* </OL>
*
* @param catalog a catalog name; "" retrieves those without a catalog
* @param schema a schema name pattern; "" retrieves those
* without a schema
* @param table a table name
* @return ResultSet each row is a foreign key column description
* @see #getImportedKeys
*/
public java.sql.ResultSet getExportedKeys(String catalog, String schema, String table) throws SQLException
{
return getImportedExportedKeys(catalog, schema, table, null, null, null);
}
 
/*
* Get a description of the foreign key columns in the foreign key
* table that reference the primary key columns of the primary key
* table (describe how one table imports another's key.) This
* should normally return a single foreign key/primary key pair
* (most tables only import a foreign key from a table once.) They
* are ordered by FKTABLE_CAT, FKTABLE_SCHEM, FKTABLE_NAME, and
* KEY_SEQ.
*
* This method is currently unimplemented.
*
* <P>Each foreign key column description has the following columns:
* <OL>
* <LI><B>PKTABLE_CAT</B> String => primary key table catalog (may be null)
* <LI><B>PKTABLE_SCHEM</B> String => primary key table schema (may be null)
* <LI><B>PKTABLE_NAME</B> String => primary key table name
* <LI><B>PKCOLUMN_NAME</B> String => primary key column name
* <LI><B>FKTABLE_CAT</B> String => foreign key table catalog (may be null)
* being exported (may be null)
* <LI><B>FKTABLE_SCHEM</B> String => foreign key table schema (may be null)
* being exported (may be null)
* <LI><B>FKTABLE_NAME</B> String => foreign key table name
* being exported
* <LI><B>FKCOLUMN_NAME</B> String => foreign key column name
* being exported
* <LI><B>KEY_SEQ</B> short => sequence number within foreign key
* <LI><B>UPDATE_RULE</B> short => What happens to
* foreign key when primary is updated:
* <UL>
* <LI> importedKeyCascade - change imported key to agree
* with primary key update
* <LI> importedKeyRestrict - do not allow update of primary
* key if it has been imported
* <LI> importedKeySetNull - change imported key to NULL if
* its primary key has been updated
* </UL>
* <LI><B>DELETE_RULE</B> short => What happens to
* the foreign key when primary is deleted.
* <UL>
* <LI> importedKeyCascade - delete rows that import a deleted key
* <LI> importedKeyRestrict - do not allow delete of primary
* key if it has been imported
* <LI> importedKeySetNull - change imported key to NULL if
* its primary key has been deleted
* </UL>
* <LI><B>FK_NAME</B> String => foreign key identifier (may be null)
* <LI><B>PK_NAME</B> String => primary key identifier (may be null)
* </OL>
*
* @param catalog a catalog name; "" retrieves those without a catalog
* @param schema a schema name pattern; "" retrieves those
* without a schema
* @param table a table name
* @return ResultSet each row is a foreign key column description
* @see #getImportedKeys
*/
public java.sql.ResultSet getCrossReference(String primaryCatalog, String primarySchema, String primaryTable, String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException
{
return getImportedExportedKeys(primaryCatalog, primarySchema, primaryTable, foreignCatalog, foreignSchema, foreignTable);
}
 
/*
* Get a description of all the standard SQL types supported by
* this database. They are ordered by DATA_TYPE and then by how
* closely the data type maps to the corresponding JDBC SQL type.
*
* <P>Each type description has the following columns:
* <OL>
* <LI><B>TYPE_NAME</B> String => Type name
* <LI><B>DATA_TYPE</B> short => SQL data type from java.sql.Types
* <LI><B>PRECISION</B> int => maximum precision
* <LI><B>LITERAL_PREFIX</B> String => prefix used to quote a literal
* (may be null)
* <LI><B>LITERAL_SUFFIX</B> String => suffix used to quote a literal
(may be null)
* <LI><B>CREATE_PARAMS</B> String => parameters used in creating
* the type (may be null)
* <LI><B>NULLABLE</B> short => can you use NULL for this type?
* <UL>
* <LI> typeNoNulls - does not allow NULL values
* <LI> typeNullable - allows NULL values
* <LI> typeNullableUnknown - nullability unknown
* </UL>
* <LI><B>CASE_SENSITIVE</B> boolean=> is it case sensitive?
* <LI><B>SEARCHABLE</B> short => can you use "WHERE" based on this type:
* <UL>
* <LI> typePredNone - No support
* <LI> typePredChar - Only supported with WHERE .. LIKE
* <LI> typePredBasic - Supported except for WHERE .. LIKE
* <LI> typeSearchable - Supported for all WHERE ..
* </UL>
* <LI><B>UNSIGNED_ATTRIBUTE</B> boolean => is it unsigned?
* <LI><B>FIXED_PREC_SCALE</B> boolean => can it be a money value?
* <LI><B>AUTO_INCREMENT</B> boolean => can it be used for an
* auto-increment value?
* <LI><B>LOCAL_TYPE_NAME</B> String => localized version of type name
* (may be null)
* <LI><B>MINIMUM_SCALE</B> short => minimum scale supported
* <LI><B>MAXIMUM_SCALE</B> short => maximum scale supported
* <LI><B>SQL_DATA_TYPE</B> int => unused
* <LI><B>SQL_DATETIME_SUB</B> int => unused
* <LI><B>NUM_PREC_RADIX</B> int => usually 2 or 10
* </OL>
*
* @return ResultSet each row is a SQL type description
*/
public java.sql.ResultSet getTypeInfo() throws SQLException
{
 
Field f[] = new Field[18];
Vector v = new Vector(); // The new ResultSet tuple stuff
 
f[0] = new Field("TYPE_NAME", Oid.VARCHAR);
f[1] = new Field("DATA_TYPE", Oid.INT2);
f[2] = new Field("PRECISION", Oid.INT4);
f[3] = new Field("LITERAL_PREFIX", Oid.VARCHAR);
f[4] = new Field("LITERAL_SUFFIX", Oid.VARCHAR);
f[5] = new Field("CREATE_PARAMS", Oid.VARCHAR);
f[6] = new Field("NULLABLE", Oid.INT2);
f[7] = new Field("CASE_SENSITIVE", Oid.BOOL);
f[8] = new Field("SEARCHABLE", Oid.INT2);
f[9] = new Field("UNSIGNED_ATTRIBUTE", Oid.BOOL);
f[10] = new Field("FIXED_PREC_SCALE", Oid.BOOL);
f[11] = new Field("AUTO_INCREMENT", Oid.BOOL);
f[12] = new Field("LOCAL_TYPE_NAME", Oid.VARCHAR);
f[13] = new Field("MINIMUM_SCALE", Oid.INT2);
f[14] = new Field("MAXIMUM_SCALE", Oid.INT2);
f[15] = new Field("SQL_DATA_TYPE", Oid.INT4);
f[16] = new Field("SQL_DATETIME_SUB", Oid.INT4);
f[17] = new Field("NUM_PREC_RADIX", Oid.INT4);
 
String sql;
if (connection.haveMinimumServerVersion("7.3"))
{
sql = "SELECT t.typname,t.oid FROM pg_catalog.pg_type t"
+ " JOIN pg_catalog.pg_namespace n ON (t.typnamespace = n.oid) "
+ " WHERE n.nspname != 'pg_toast'";
}
else
{
sql = "SELECT typname,oid FROM pg_type" +
" WHERE NOT (typname ~ '^pg_toast_') ";
}
 
ResultSet rs = connection.createStatement().executeQuery(sql);
// cache some results, this will keep memory useage down, and speed
// things up a little.
byte bZero[] = connection.encodeString("0");
byte b10[] = connection.encodeString("10");
byte bf[] = connection.encodeString("f");
byte bt[] = connection.encodeString("t");
byte bliteral[] = connection.encodeString("'");
byte bNullable[] = connection.encodeString(Integer.toString(java.sql.DatabaseMetaData.typeNullable));
byte bSearchable[] = connection.encodeString(Integer.toString(java.sql.DatabaseMetaData.typeSearchable));
 
while (rs.next())
{
byte[][] tuple = new byte[18][];
String typname = rs.getString(1);
int typeOid = (int)rs.getLong(2);
 
tuple[0] = connection.encodeString(typname);
tuple[1] = connection.encodeString(Integer.toString(connection.getTypeInfo().getSQLType(typname)));
tuple[2] = connection.encodeString(Integer.toString(connection.getTypeInfo().getMaximumPrecision(typeOid)));
 
if (connection.getTypeInfo().requiresQuoting(typeOid))
{
tuple[3] = bliteral;
tuple[4] = bliteral;
}
 
tuple[6] = bNullable; // all types can be null
tuple[7] = connection.getTypeInfo().isCaseSensitive(typeOid) ? bt : bf;
tuple[8] = bSearchable; // any thing can be used in the WHERE clause
tuple[9] = connection.getTypeInfo().isSigned(typeOid) ? bf : bt;
tuple[10] = bf; // false for now - must handle money
tuple[11] = bf; // false - it isn't autoincrement
tuple[13] = bZero; // min scale is zero
// only numeric can supports a scale.
tuple[14] = (typeOid == Oid.NUMERIC) ? connection.encodeString("1000") : bZero;
 
// 12 - LOCAL_TYPE_NAME is null
// 15 & 16 are unused so we return null
tuple[17] = b10; // everything is base 10
v.addElement(tuple);
 
// add pseudo-type serial, bigserial
if ( typname.equals("int4") )
{
byte[][] tuple1 = (byte[][])tuple.clone();
 
tuple1[0] = connection.encodeString("serial");
tuple1[11] = bt;
v.addElement(tuple1);
}
else if ( typname.equals("int8") )
{
byte[][] tuple1 = (byte[][])tuple.clone();
 
tuple1[0] = connection.encodeString("bigserial");
tuple1[11] = bt;
v.addElement(tuple1);
}
 
}
rs.close();
 
return (ResultSet) ((BaseStatement)createMetaDataStatement()).createDriverResultSet(f, v);
}
 
/*
* Get a description of a table's indices and statistics. They are
* ordered by NON_UNIQUE, TYPE, INDEX_NAME, and ORDINAL_POSITION.
*
* <P>Each index column description has the following columns:
* <OL>
* <LI><B>TABLE_CAT</B> String => table catalog (may be null)
* <LI><B>TABLE_SCHEM</B> String => table schema (may be null)
* <LI><B>TABLE_NAME</B> String => table name
* <LI><B>NON_UNIQUE</B> boolean => Can index values be non-unique?
* false when TYPE is tableIndexStatistic
* <LI><B>INDEX_QUALIFIER</B> String => index catalog (may be null);
* null when TYPE is tableIndexStatistic
* <LI><B>INDEX_NAME</B> String => index name; null when TYPE is
* tableIndexStatistic
* <LI><B>TYPE</B> short => index type:
* <UL>
* <LI> tableIndexStatistic - this identifies table statistics that are
* returned in conjuction with a table's index descriptions
* <LI> tableIndexClustered - this is a clustered index
* <LI> tableIndexHashed - this is a hashed index
* <LI> tableIndexOther - this is some other style of index
* </UL>
* <LI><B>ORDINAL_POSITION</B> short => column sequence number
* within index; zero when TYPE is tableIndexStatistic
* <LI><B>COLUMN_NAME</B> String => column name; null when TYPE is
* tableIndexStatistic
* <LI><B>ASC_OR_DESC</B> String => column sort sequence, "A" => ascending
* "D" => descending, may be null if sort sequence is not supported;
* null when TYPE is tableIndexStatistic
* <LI><B>CARDINALITY</B> int => When TYPE is tableIndexStatisic then
* this is the number of rows in the table; otherwise it is the
* number of unique values in the index.
* <LI><B>PAGES</B> int => When TYPE is tableIndexStatisic then
* this is the number of pages used for the table, otherwise it
* is the number of pages used for the current index.
* <LI><B>FILTER_CONDITION</B> String => Filter condition, if any.
* (may be null)
* </OL>
*
* @param catalog a catalog name; "" retrieves those without a catalog
* @param schema a schema name pattern; "" retrieves those without a schema
* @param table a table name
* @param unique when true, return only indices for unique values;
* when false, return indices regardless of whether unique or not
* @param approximate when true, result is allowed to reflect approximate
* or out of data values; when false, results are requested to be
* accurate
* @return ResultSet each row is an index column description
*/
// Implementation note: This is required for Borland's JBuilder to work
public java.sql.ResultSet getIndexInfo(String catalog, String schema, String tableName, boolean unique, boolean approximate) throws SQLException
{
/* This is a complicated function because we have three possible
* situations:
* <= 7.2 no schemas, single column functional index
* 7.3 schemas, single column functional index
* >= 7.4 schemas, multi-column expressional index
* >= 8.3 supports ASC/DESC column info
* >= 9.0 no longer renames index columns on a table column rename,
* so we must look at the table attribute names
*
* with the single column functional index we need an extra
* join to the table's pg_attribute data to get the column
* the function operates on.
*/
String sql;
if (connection.haveMinimumServerVersion("8.3"))
{
sql = "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, "
+ " ct.relname AS TABLE_NAME, NOT i.indisunique AS NON_UNIQUE, "
+ " NULL AS INDEX_QUALIFIER, ci.relname AS INDEX_NAME, "
+ " CASE i.indisclustered "
+ " WHEN true THEN " + java.sql.DatabaseMetaData.tableIndexClustered
+ " ELSE CASE am.amname "
+ " WHEN 'hash' THEN " + java.sql.DatabaseMetaData.tableIndexHashed
+ " ELSE " + java.sql.DatabaseMetaData.tableIndexOther
+ " END "
+ " END AS TYPE, "
+ " (i.keys).n AS ORDINAL_POSITION, "
+ " pg_catalog.pg_get_indexdef(ci.oid, (i.keys).n, false) AS COLUMN_NAME, "
+ " CASE am.amcanorder "
+ " WHEN true THEN CASE i.indoption[(i.keys).n - 1] & 1 "
+ " WHEN 1 THEN 'D' "
+ " ELSE 'A' "
+ " END "
+ " ELSE NULL "
+ " END AS ASC_OR_DESC, "
+ " ci.reltuples AS CARDINALITY, "
+ " ci.relpages AS PAGES, "
+ " pg_catalog.pg_get_expr(i.indpred, i.indrelid) AS FILTER_CONDITION "
+ "FROM pg_catalog.pg_class ct "
+ " JOIN pg_catalog.pg_namespace n ON (ct.relnamespace = n.oid) "
+ " JOIN (SELECT i.indexrelid, i.indrelid, i.indoption, "
+ " i.indisunique, i.indisclustered, i.indpred, "
+ " i.indexprs, "
+ " information_schema._pg_expandarray(i.indkey) AS keys "
+ " FROM pg_catalog.pg_index i) i "
+ " ON (ct.oid = i.indrelid) "
+ " JOIN pg_catalog.pg_class ci ON (ci.oid = i.indexrelid) "
+ " JOIN pg_catalog.pg_am am ON (ci.relam = am.oid) "
+ "WHERE true ";
 
if (schema != null && !"".equals(schema))
{
sql += " AND n.nspname = '" + escapeQuotes(schema) + "' ";
}
} else {
String select;
String from;
String where = "";
 
if (connection.haveMinimumServerVersion("7.3"))
{
select = "SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, ";
from = " FROM pg_catalog.pg_namespace n, pg_catalog.pg_class ct, pg_catalog.pg_class ci, pg_catalog.pg_attribute a, pg_catalog.pg_am am ";
where = " AND n.oid = ct.relnamespace ";
 
if (!connection.haveMinimumServerVersion("7.4")) {
from += ", pg_catalog.pg_attribute ai, pg_catalog.pg_index i LEFT JOIN pg_catalog.pg_proc ip ON (i.indproc = ip.oid) ";
where += " AND ai.attnum = i.indkey[0] AND ai.attrelid = ct.oid ";
} else {
from += ", pg_catalog.pg_index i ";
}
if (schema != null && ! "".equals(schema))
{
where += " AND n.nspname = '" + escapeQuotes(schema) + "' ";
}
}
else
{
select = "SELECT NULL AS TABLE_CAT, NULL AS TABLE_SCHEM, ";
from = " FROM pg_class ct, pg_class ci, pg_attribute a, pg_am am, pg_attribute ai, pg_index i LEFT JOIN pg_proc ip ON (i.indproc = ip.oid) ";
where = " AND ai.attnum = i.indkey[0] AND ai.attrelid = ct.oid ";
}
 
sql = select +
" ct.relname AS TABLE_NAME, NOT i.indisunique AS NON_UNIQUE, NULL AS INDEX_QUALIFIER, ci.relname AS INDEX_NAME, " +
" CASE i.indisclustered " +
" WHEN true THEN " + java.sql.DatabaseMetaData.tableIndexClustered +
" ELSE CASE am.amname " +
" WHEN 'hash' THEN " + java.sql.DatabaseMetaData.tableIndexHashed +
" ELSE " + java.sql.DatabaseMetaData.tableIndexOther +
" END " +
" END AS TYPE, " +
" a.attnum AS ORDINAL_POSITION, ";
 
if( connection.haveMinimumServerVersion("7.4"))
{
sql += " CASE WHEN i.indexprs IS NULL THEN a.attname ELSE pg_catalog.pg_get_indexdef(ci.oid,a.attnum,false) END AS COLUMN_NAME, ";
}
else
{
sql += " CASE i.indproc WHEN 0 THEN a.attname ELSE ip.proname || '(' || ai.attname || ')' END AS COLUMN_NAME, ";
}
 
 
sql += " NULL AS ASC_OR_DESC, " +
" ci.reltuples AS CARDINALITY, " +
" ci.relpages AS PAGES, ";
 
if( connection.haveMinimumServerVersion("7.3"))
{
sql += " pg_catalog.pg_get_expr(i.indpred, i.indrelid) AS FILTER_CONDITION ";
}
else if( connection.haveMinimumServerVersion("7.2"))
{
sql += " pg_get_expr(i.indpred, i.indrelid) AS FILTER_CONDITION ";
}
else
{
sql += " NULL AS FILTER_CONDITION ";
}
 
sql += from +
" WHERE ct.oid=i.indrelid AND ci.oid=i.indexrelid AND a.attrelid=ci.oid AND ci.relam=am.oid " +
where;
}
 
sql += " AND ct.relname = '" + escapeQuotes(tableName) + "' ";
 
if (unique)
{
sql += " AND i.indisunique ";
}
sql += " ORDER BY NON_UNIQUE, TYPE, INDEX_NAME, ORDINAL_POSITION ";
return createMetaDataStatement().executeQuery(sql);
}
 
/**
* Tokenize based on words not on single characters.
*/
private static Vector tokenize(String input, String delimiter) {
Vector result = new Vector();
int start = 0;
int end = input.length();
int delimiterSize = delimiter.length();
 
while (start < end)
{
int delimiterIndex = input.indexOf(delimiter, start);
if (delimiterIndex < 0)
{
result.addElement(input.substring(start));
break;
}
else
{
String token = input.substring(start, delimiterIndex);
result.addElement(token);
start = delimiterIndex + delimiterSize;
}
}
return result;
}
 
// ** JDBC 2 Extensions **
 
/*
* Does the database support the given result set type?
*
* @param type - defined in java.sql.ResultSet
* @return true if so; false otherwise
* @exception SQLException - if a database access error occurs
*/
public boolean supportsResultSetType(int type) throws SQLException
{
// The only type we don't support
return type != java.sql.ResultSet.TYPE_SCROLL_SENSITIVE;
}
 
 
/*
* Does the database support the concurrency type in combination
* with the given result set type?
*
* @param type - defined in java.sql.ResultSet
* @param concurrency - type defined in java.sql.ResultSet
* @return true if so; false otherwise
* @exception SQLException - if a database access error occurs
*/
public boolean supportsResultSetConcurrency(int type, int concurrency) throws SQLException
{
// These combinations are not supported!
if (type == java.sql.ResultSet.TYPE_SCROLL_SENSITIVE)
return false;
 
// We do support Updateable ResultSets
if (concurrency == java.sql.ResultSet.CONCUR_UPDATABLE)
return true;
 
// Everything else we do
return true;
}
 
 
/* lots of unsupported stuff... */
public boolean ownUpdatesAreVisible(int type) throws SQLException
{
return true;
}
 
public boolean ownDeletesAreVisible(int type) throws SQLException
{
return true;
}
 
public boolean ownInsertsAreVisible(int type) throws SQLException
{
// indicates that
return true;
}
 
public boolean othersUpdatesAreVisible(int type) throws SQLException
{
return false;
}
 
public boolean othersDeletesAreVisible(int i) throws SQLException
{
return false;
}
 
public boolean othersInsertsAreVisible(int type) throws SQLException
{
return false;
}
 
public boolean updatesAreDetected(int type) throws SQLException
{
return false;
}
 
public boolean deletesAreDetected(int i) throws SQLException
{
return false;
}
 
public boolean insertsAreDetected(int type) throws SQLException
{
return false;
}
 
/*
* Indicates whether the driver supports batch updates.
*/
public boolean supportsBatchUpdates() throws SQLException
{
return true;
}
 
/**
*
* @param catalog String
* @param schemaPattern String
* @param typeNamePattern String
* @param types int[]
* @throws SQLException
* @return ResultSet
*/
public java.sql.ResultSet getUDTs(String catalog,
String schemaPattern,
String typeNamePattern,
int[] types
) throws SQLException
{
String sql = "select "
+ "null as type_cat, n.nspname as type_schem, t.typname as type_name, null as class_name, "
+ "CASE WHEN t.typtype='c' then " + java.sql.Types.STRUCT + " else " + java.sql.Types.DISTINCT + " end as data_type, pg_catalog.obj_description(t.oid, 'pg_type') "
+ "as remarks, CASE WHEN t.typtype = 'd' then (select CASE";
 
for (Iterator i = connection.getTypeInfo().getPGTypeNamesWithSQLTypes(); i.hasNext();) {
String pgType = (String)i.next();
int sqlType = connection.getTypeInfo().getSQLType(pgType);
sql += " when typname = '" + escapeQuotes(pgType) + "' then " + sqlType;
}
 
sql += " else " + java.sql.Types.OTHER + " end from pg_type where oid=t.typbasetype) "
+ "else null end as base_type "
+ "from pg_catalog.pg_type t, pg_catalog.pg_namespace n where t.typnamespace = n.oid and n.nspname != 'pg_catalog' and n.nspname != 'pg_toast'";
 
 
 
String toAdd = "";
if ( types != null )
{
toAdd += " and (false ";
for (int i = 0; i < types.length; i++)
{
switch (types[i] )
{
case java.sql.Types.STRUCT:
toAdd += " or t.typtype = 'c'";
break;
case java.sql.Types.DISTINCT:
toAdd += " or t.typtype = 'd'";
break;
}
}
toAdd += " ) ";
}
else
{
toAdd += " and t.typtype IN ('c','d') ";
}
// spec says that if typeNamePattern is a fully qualified name
// then the schema and catalog are ignored
 
if (typeNamePattern != null)
{
// search for qualifier
int firstQualifier = typeNamePattern.indexOf('.') ;
int secondQualifier = typeNamePattern.lastIndexOf('.');
 
if ( firstQualifier != -1 ) // if one of them is -1 they both will be
{
if ( firstQualifier != secondQualifier )
{
// we have a catalog.schema.typename, ignore catalog
schemaPattern = typeNamePattern.substring(firstQualifier + 1, secondQualifier);
}
else
{
// we just have a schema.typename
schemaPattern = typeNamePattern.substring(0, firstQualifier);
}
// strip out just the typeName
typeNamePattern = typeNamePattern.substring(secondQualifier + 1);
}
toAdd += " and t.typname like '" + escapeQuotes(typeNamePattern) + "'";
}
 
// schemaPattern may have been modified above
if ( schemaPattern != null)
{
toAdd += " and n.nspname like '" + escapeQuotes(schemaPattern) + "'";
}
sql += toAdd;
sql += " order by data_type, type_schem, type_name";
java.sql.ResultSet rs = createMetaDataStatement().executeQuery(sql);
 
return rs;
}
 
 
/*
* Retrieves the connection that produced this metadata object.
*
* @return the connection that produced this metadata object
*/
public java.sql.Connection getConnection() throws SQLException
{
return (java.sql.Connection)connection;
}
 
/* I don't find these in the spec!?! */
 
public boolean rowChangesAreDetected(int type) throws SQLException
{
return false;
}
 
public boolean rowChangesAreVisible(int type) throws SQLException
{
return false;
}
 
protected java.sql.Statement createMetaDataStatement() throws SQLException
{
return ((AbstractJdbc2Connection)connection).createStatement(java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE, java.sql.ResultSet.CONCUR_READ_ONLY);
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/task/TodoListPanel.java
641,16 → 641,13
 
public void stateChanged(int state) {
if (state == ModelStateListener.STATE_OK) {
this.reloadPanel.setSleeping(true);
 
this.reloadPanel.setMode(ReloadPanel.MODE_EMPTY);
}
if (state == ModelStateListener.STATE_DEAD) {
this.reloadPanel.setMode(ReloadPanel.MODE_BLINK);
this.reloadPanel.setSleeping(false);
}
if (state == ModelStateListener.STATE_RELOADING) {
this.reloadPanel.setMode(ReloadPanel.MODE_ROTATE);
this.reloadPanel.setSleeping(false);
}
}
 
/trunk/OpenConcerto/src/org/openconcerto/task/config/TaskNX.java
14,6 → 14,7
package org.openconcerto.task.config;
 
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLBase;
import org.openconcerto.sql.ui.ConnexionPanel;
import org.openconcerto.sql.utils.Exiter;
import org.openconcerto.task.ModelStateListener;
96,7 → 97,7
}
 
public static void main(String[] args) {
System.setProperty("org.openconcerto.sql.structure.useXML", "true");
System.setProperty(SQLBase.STRUCTURE_USE_XML, "true");
Configuration.setInstance(TaskPropsConfiguration.create());
final Runnable r = new Runnable() {
 
/trunk/OpenConcerto/src/org/openconcerto/task/config/ComptaBasePropsConfiguration.java
166,7 → 166,7
final DBSystemRoot b = this.getSystemRoot();
// now map the societe
final String societeBaseName = this.getSocieteBaseName();
b.getRootsToMap().add(societeBaseName);
b.addRootToMap(societeBaseName);
try {
b.reload(Collections.singleton(societeBaseName));
} catch (SQLException e) {
/trunk/OpenConcerto/src/org/openconcerto/task/config/TaskAdminNX.java
14,6 → 14,7
package org.openconcerto.task.config;
 
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLBase;
import org.openconcerto.sql.utils.Exiter;
import org.openconcerto.task.ui.UserRightsPrefPanel;
 
32,7 → 33,7
public class TaskAdminNX {
 
public static void main(String[] args) {
System.setProperty("org.openconcerto.sql.structure.useXML", "true");
System.setProperty(SQLBase.STRUCTURE_USE_XML, "true");
Configuration.setInstance(TaskPropsConfiguration.create());
SwingUtilities.invokeLater(new Runnable() {
 
/trunk/OpenConcerto/src/org/openconcerto/task/ui/UserRightPanelDetail.java
184,7 → 184,7
rowV.put("ID_USER_COMMON_TO", toUser.getId());
rowV.put(field, Boolean.TRUE);
SQLSelect sel = new SQLSelect(defaultBase);
sel.addSelectStar("TACHE_RIGHTS");
sel.addSelectStar(tableTacheRights);
Where where = new Where(tableTacheRights.getField("ID_USER_COMMON"), "=", user.getId());
where = where.and(new Where(tableTacheRights.getField("ID_USER_COMMON_TO"), "=", toUser.getId()));
sel.setWhere(where);
/trunk/OpenConcerto/src/org/openconcerto/task/UserTaskRight.java
23,12 → 23,15
 
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
 
import org.apache.commons.dbutils.ResultSetHandler;
 
public class UserTaskRight {
private static Map<User, List<UserTaskRight>> cache = new HashMap<User, List<UserTaskRight>>();
private int idUser;
private int idToUser;
private boolean canRead;
37,15 → 40,10
private boolean canValidate;
 
/**
* @param idUser
* @param idToUser
* @param canRead
* @param canModify
* @param canWrite
* @param canValidate
* Rights for tasks associated to a user. UserTaskRight is immutable
*
*/
public UserTaskRight(int idUser, int idToUser, boolean canRead, boolean canModify, boolean canAdd, boolean canValidate) {
super();
this.idUser = idUser;
this.idToUser = idToUser;
this.canRead = canRead;
78,7 → 76,14
return idUser;
}
 
public static void clearCache() {
cache.clear();
}
 
public static List<UserTaskRight> getUserTaskRight(final User selectedUser) {
List<UserTaskRight> result = cache.get(selectedUser);
if (result == null) {
 
final SQLTable rightsT = Configuration.getInstance().getSystemRoot().findTable("TACHE_RIGHTS", true);
final SQLField userF = rightsT.getField("ID_USER_COMMON");
final SQLTable userT = rightsT.getForeignTable(userF.getName());
87,9 → 92,9
sel.setWhere(new Where(userF, "=", selectedUser.getId()));
String req = sel.toString();
 
SQLDataSource dataSource = Configuration.getInstance().getBase().getDataSource();
final SQLDataSource dataSource = Configuration.getInstance().getBase().getDataSource();
@SuppressWarnings("unchecked")
List<UserTaskRight> l = (List<UserTaskRight>) dataSource.execute(req, new ResultSetHandler() {
final List<UserTaskRight> l = (List<UserTaskRight>) dataSource.execute(req, new ResultSetHandler() {
 
public Object handle(ResultSet rs) throws SQLException {
List<UserTaskRight> list = new Vector<UserTaskRight>();
111,8 → 116,11
return list;
}
});
return l;
cache.put(selectedUser, l);
result = l;
}
return result;
}
 
@Override
public String toString() {
/trunk/OpenConcerto/src/org/openconcerto/erp/preferences/GenerationDocumentComptaPreferencePanel.java
15,7 → 15,7
 
import org.openconcerto.erp.core.finance.accounting.report.BalanceSheet;
import org.openconcerto.erp.core.finance.accounting.report.GrandLivreSheet;
import org.openconcerto.erp.core.finance.accounting.report.JournauxSheet;
import org.openconcerto.erp.core.finance.accounting.report.JournauxSheetXML;
import org.openconcerto.utils.Tuple2;
 
public class GenerationDocumentComptaPreferencePanel extends AbstractGenerationDocumentPreferencePanel {
23,7 → 23,7
public GenerationDocumentComptaPreferencePanel() {
super();
this.mapKeyLabel.put(Tuple2.create(GrandLivreSheet.TEMPLATE_ID, GrandLivreSheet.TEMPLATE_PROPERTY_NAME), GrandLivreSheet.TEMPLATE_ID);
this.mapKeyLabel.put(Tuple2.create(JournauxSheet.TEMPLATE_ID, JournauxSheet.TEMPLATE_PROPERTY_NAME), JournauxSheet.TEMPLATE_ID);
this.mapKeyLabel.put(Tuple2.create(JournauxSheetXML.TEMPLATE_ID, JournauxSheetXML.TEMPLATE_PROPERTY_NAME), JournauxSheetXML.TEMPLATE_ID);
this.mapKeyLabel.put(Tuple2.create(BalanceSheet.TEMPLATE_ID, BalanceSheet.TEMPLATE_PROPERTY_NAME), BalanceSheet.TEMPLATE_ID);
// uiInit();
}
/trunk/OpenConcerto/src/org/openconcerto/erp/preferences/TemplateNXProps.java
17,7 → 17,7
import org.openconcerto.erp.core.customerrelationship.customer.report.FicheClientXmlSheet;
import org.openconcerto.erp.core.finance.accounting.report.BalanceSheet;
import org.openconcerto.erp.core.finance.accounting.report.GrandLivreSheet;
import org.openconcerto.erp.core.finance.accounting.report.JournauxSheet;
import org.openconcerto.erp.core.finance.accounting.report.JournauxSheetXML;
import org.openconcerto.erp.core.humanresources.payroll.report.EtatChargesPayeSheet;
import org.openconcerto.erp.core.humanresources.payroll.report.FichePayeSheet;
import org.openconcerto.erp.core.humanresources.payroll.report.LivrePayeSheet;
136,7 → 136,7
register(ListeVenteXmlSheet.TEMPLATE_ID, ListeVenteXmlSheet.TEMPLATE_PROPERTY_NAME, null);
register(BalanceSheet.TEMPLATE_ID, BalanceSheet.TEMPLATE_PROPERTY_NAME, BalanceSheet.TEMPLATE_ID);
register(GrandLivreSheet.TEMPLATE_ID, GrandLivreSheet.TEMPLATE_PROPERTY_NAME, GrandLivreSheet.TEMPLATE_ID);
register(JournauxSheet.TEMPLATE_ID, JournauxSheet.TEMPLATE_PROPERTY_NAME, JournauxSheet.TEMPLATE_ID);
register(JournauxSheetXML.TEMPLATE_ID, JournauxSheetXML.TEMPLATE_PROPERTY_NAME, JournauxSheetXML.TEMPLATE_ID);
register(EtatChargesPayeSheet.TEMPLATE_ID, EtatChargesPayeSheet.TEMPLATE_PROPERTY_NAME, "Etat des charges");
register(FichePayeSheet.TEMPLATE_ID, FichePayeSheet.TEMPLATE_PROPERTY_NAME, "Fiche paye");
register(LivrePayeSheet.TEMPLATE_ID, LivrePayeSheet.TEMPLATE_PROPERTY_NAME, "Livre paye");
/trunk/OpenConcerto/src/org/openconcerto/erp/config/mappingCompta.xml
1780,6 → 1780,7
<FIELD name="T_TVA" label="Total TVA" titlelabel="Total TVA" />
<FIELD name="T_TTC" label="Total TTC" titlelabel="Total TTC" />
<FIELD name="ID_TAXE" label="Taxe" titlelabel="Taxe" />
<FIELD name="ID_TAXE_PORT" label="TVA sur port" titlelabel="TVA sur port" />
<FIELD name="ID_MOUVEMENT" label="N° de mouvement" titlelabel="N° de mouvement" />
<FIELD name="INFOS" label="Informations complémentaires"
titlelabel="Informations" />
/trunk/OpenConcerto/src/org/openconcerto/erp/config/InstallationPanel.java
202,7 → 202,7
 
// we need to upgrade all roots
// ///////////////////////////
conf.getSystemRoot().getRootsToMap().clear();
conf.getSystemRoot().mapAllRoots();
conf.getSystemRoot().refetch();
 
final Set<String> childrenNames = conf.getSystemRoot().getChildrenNames();
1160,6 → 1160,28
}
}
}
 
// Change VF
{
SQLTable tableVenteFacture = root.getTable("SAISIE_VENTE_FACTURE");
 
AlterTable tVF = new AlterTable(tableVenteFacture);
boolean alterVF = false;
 
if (!tableVenteFacture.getFieldsName().contains("ID_TAXE_PORT")) {
tVF.addForeignColumn("ID_TAXE_PORT", root.findTable("TAXE"));
alterVF = true;
}
if (alterVF) {
try {
ds.execute(tVF.asString());
tableVenteFacture.getSchema().updateVersion();
} catch (SQLException ex) {
throw new IllegalStateException("Erreur lors de l'ajout des champs sur la table SAISIE_VENTE_FACTURE", ex);
}
}
}
 
// Change Fournisseur
{
SQLTable tableFournisseur = root.getTable("FOURNISSEUR");
1541,7 → 1563,7
CorrectOrder orderCorrect = new CorrectOrder(sysRoot);
orderCorrect.change(tableCommercial);
 
new AddFK(sysRoot).change(root);
new AddFK(sysRoot).changeAll(root);
root.getSchema().updateVersion();
root.refetch();
// load graph now so that it's coherent with the structure
1839,7 → 1861,7
}
 
// FK
new AddFK(root.getDBSystemRoot()).change(root);
new AddFK(root.getDBSystemRoot()).changeAll(root);
}
 
private void updateSocieteTable(DBRoot root) throws SQLException {
/trunk/OpenConcerto/src/org/openconcerto/erp/config/ServerFinderConfig.java
15,6 → 15,7
 
import org.openconcerto.sql.model.DBSystemRoot;
import org.openconcerto.sql.model.SQLServer;
import org.openconcerto.sql.model.SQLSystem;
import org.openconcerto.utils.CompareUtils;
import org.openconcerto.utils.cc.IClosure;
 
53,6 → 54,10
return type;
}
 
public SQLSystem getSystem() {
return SQLSystem.get(this.getType());
}
 
public void setType(String type) {
this.type = type;
}
202,11 → 207,11
} else {
host = this.getIp();
}
final SQLServer server = new SQLServer(this.getType(), host, String.valueOf(this.getPort()), getOpenconcertoLogin(), getOpenconcertoPassword(), new IClosure<DBSystemRoot>() {
final SQLServer server = new SQLServer(this.getSystem(), host, String.valueOf(this.getPort()), getOpenconcertoLogin(), getOpenconcertoPassword(), new IClosure<DBSystemRoot>() {
@Override
public void executeChecked(DBSystemRoot input) {
// don't map all the database
input.getRootsToMap().add(root);
input.setRootToMap(root);
}
}, null);
 
229,12 → 234,12
host = this.getIp();
}
if (this.getType().equals(ServerFinderConfig.POSTGRESQL)) {
final SQLServer server = new SQLServer(this.getType(), host, String.valueOf(this.getPort()), user, password, new IClosure<DBSystemRoot>() {
final SQLServer server = new SQLServer(this.getSystem(), host, String.valueOf(this.getPort()), user, password, new IClosure<DBSystemRoot>() {
 
@Override
public void executeChecked(DBSystemRoot input) {
// don't map all the database
input.getRootsToMap().add("postgres");
input.setRootToMap("postgres");
}
}, null);
Number n = (Number) server.getOrCreateBase("postgres").getDataSource().executeScalar("SELECT COUNT(*) FROM pg_user WHERE usename='openconcerto'");
/trunk/OpenConcerto/src/org/openconcerto/erp/config/ComptaPropsConfiguration.java
139,6 → 139,7
import org.openconcerto.erp.generationDoc.provider.UserCreateInitialsValueProvider;
import org.openconcerto.erp.generationDoc.provider.UserCurrentInitialsValueProvider;
import org.openconcerto.erp.generationDoc.provider.UserModifyInitialsValueProvider;
import org.openconcerto.erp.injector.AchatAvoirSQLInjector;
import org.openconcerto.erp.injector.ArticleCommandeEltSQLInjector;
import org.openconcerto.erp.injector.BonFactureSQLInjector;
import org.openconcerto.erp.injector.BrFactureAchatSQLInjector;
359,7 → 360,7
setProperty("systemRoot", cProperty.getProperty("db.name"));
// Storage
props.put("storage.server", cProperty.getProperty("storage.server"));
progress.dispose();
 
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(new JFrame(), "Impossible récupérer les informations de connexion");
373,6 → 374,7
JOptionPane.showMessageDialog(new JFrame(), "Connexion impossible au Cloud");
System.exit(1);
}
progress.dispose();
}
StorageEngines.getInstance().addEngine(new CloudStorageEngine());
} else {
410,7 → 412,9
private final ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "Loading listener thread");
final Thread thread = new Thread(r, "Loading listener thread");
thread.setDaemon(true);
return thread;
}
});
private ScheduledFuture<?> future = null;
427,6 → 431,7
@Override
public void run() {
f.setVisible(false);
f.dispose();
}
});
} else if (this.future == null) {
760,6 → 765,7
 
private void setSocieteSQLInjector() {
final DBRoot rootSociete = getRootSociete();
new AchatAvoirSQLInjector(rootSociete);
new ArticleCommandeEltSQLInjector(rootSociete);
new CommandeCliCommandeSQLInjector(rootSociete);
new FactureAvoirSQLInjector(rootSociete);
794,7 → 800,7
if (getRootSociete().getTable("CLIENT").getFieldsName().contains("LOCALISATION")) {
showAs.show("CLIENT", "NOM", "LOCALISATION");
} else {
showAs.show("CLIENT", "FORME_JURIDIQUE", "NOM");
showAs.show("CLIENT", "NOM");
}
 
showAs.show("CLASSEMENT_CONVENTIONNEL", "NIVEAU", "COEFF");
911,13 → 917,7
}
}
TemplateNXProps.getInstance();
// Chargement du graphe
new Thread() {
public void run() {
Configuration.getInstance().getSystemRoot().getGraph();
}
}.start();
}
 
private void setMapper() {
GlobalMapper mapper = GlobalMapper.getInstance();
/trunk/OpenConcerto/src/org/openconcerto/erp/config/Gestion.java
41,7 → 41,6
import org.openconcerto.utils.protocol.Helper;
 
import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.Image;
66,9 → 65,6
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;
 
public class Gestion {
 
141,7 → 137,7
System.setProperty("org.openconcerto.sql.editpanel.endAdd", "true");
System.setProperty("org.openconcerto.sql.listPanel.deafEditPanel", "true");
System.setProperty("org.openconcerto.ui.addComboButton", "true");
System.setProperty("org.openconcerto.sql.structure.useXML", "true");
System.setProperty(SQLBase.STRUCTURE_USE_XML, "true");
// don't put any suffix, rely on Animator
System.setProperty(UISQLComponent.REQUIRED_SUFFIX_PROP, "");
System.setProperty(ElementComboBox.CAN_MODIFY, "true");
190,6 → 186,10
if (Boolean.valueOf(conf.getProperty("minimal", "false"))) {
System.setProperty(MINIMAL_PROP, Boolean.TRUE.toString());
}
if (Boolean.valueOf(conf.getProperty("statelessTable", "false"))) {
System.setProperty(IListe.STATELESS_TABLE_PROP, Boolean.TRUE.toString());
}
 
if (conf.getProperty("odsViewer") != null) {
System.setProperty("org.openconcerto.oo.useODSViewer", Boolean.valueOf(conf.getProperty("odsViewer")).toString());
}
212,7 → 212,8
}
}
try {
conf.getBase();
// ensure consistent state
conf.getSystemRoot().getGraph();
} catch (Exception e) {
System.out.println("Init phase 1 error:" + (System.currentTimeMillis() - t4) + "ms");
ExceptionHandler.die("Erreur de connexion à la base de données", e);
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/ModulePreferencePanel.java
72,7 → 72,7
if (comp instanceof SQLTextCombo) {
((SQLTextCombo) comp).initCache(createCache(prefPanel));
} else if (comp instanceof SQLSearchableTextCombo) {
((SQLSearchableTextCombo) comp).initCacheLater(new ISQLListModel(createCache(prefPanel)));
((SQLSearchableTextCombo) comp).initCache(new ISQLListModel(createCache(prefPanel)).load());
}
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/ModuleLauncher.java
47,7 → 47,13
// always update dist/ to avoid out of date problems
final File distDir = new File(moduleDir, "dist");
FileUtils.mkdir_p(distDir);
final File jar = new ModulePackager(propsFile, classes).writeToDir(distDir);
final ModulePackager pkger = new ModulePackager(propsFile, classes);
final File libDir = new File(moduleDir, "lib");
if (libDir.exists()) {
pkger.setSkipDuplicateFiles(true);
pkger.addJarsFromDir(libDir);
}
final File jar = pkger.writeToDir(distDir);
// to avoid out of date modules from OpenConcerto (e.g. when launching this module, the jars
// of MODULES_DIR are used for dependencies)
FileUtils.mkdir_p(Gestion.MODULES_DIR);
/trunk/OpenConcerto/src/org/openconcerto/erp/modules/ModuleManager.java
95,7 → 95,7
 
private static final Logger L = Logger.getLogger(ModuleManager.class.getPackage().getName());
private static final Executor exec = new ThreadPoolExecutor(0, 2, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), new ThreadFactory(ModuleManager.class.getSimpleName()
+ " executor thread "));
+ " executor thread ", Boolean.TRUE));
 
private static final int MIN_VERSION = 0;
private static final String MODULE_COLNAME = "MODULE_NAME";
756,12 → 756,11
}
}
 
private void setupComponents(final AbstractModule module) throws SQLException {
private void setupComponents(final AbstractModule module, final Tuple2<Set<String>, Set<SQLName>> alreadyCreatedItems) throws SQLException {
assert SwingUtilities.isEventDispatchThread();
final String id = module.getFactory().getID();
if (!this.modulesComponents.containsKey(id)) {
final SQLElementDirectory dir = getDirectory();
final Tuple2<Set<String>, Set<SQLName>> alreadyCreatedItems = getCreatedItems(id);
final ComponentsContext ctxt = new ComponentsContext(dir, getRoot(), alreadyCreatedItems.get0(), alreadyCreatedItems.get1());
module.setupComponents(ctxt);
this.modulesComponents.put(id, ctxt);
854,9 → 853,12
final ModuleFactory f = module.getFactory();
final String id = f.getID();
try {
// do the request here instead of in the EDT in setupComponents()
assert !this.runningModules.containsKey(id) : "Doing a request for nothing";
final Tuple2<Set<String>, Set<SQLName>> createdItems = getCreatedItems(id);
// execute right away if possible, allowing the caller to handle any exceptions
if (SwingUtilities.isEventDispatchThread()) {
startModule(module);
startModule(module, createdItems);
} else {
// keep the for outside to avoid halting the EDT too long
SwingUtilities.invokeLater(new Runnable() {
863,7 → 865,7
@Override
public void run() {
try {
startModule(module);
startModule(module, createdItems);
} catch (Exception e) {
ExceptionHandler.handle(MainFrame.getInstance(), "Unable to start " + f, e);
}
921,9 → 923,9
}
}
 
private final void startModule(final AbstractModule module) throws Exception {
private final void startModule(final AbstractModule module, final Tuple2<Set<String>, Set<SQLName>> createdItems) throws Exception {
assert SwingUtilities.isEventDispatchThread();
this.setupComponents(module);
this.setupComponents(module, createdItems);
module.start();
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/action/NouvelleConnexionAction.java
51,6 → 51,7
import org.openconcerto.ui.FrameUtil;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.JImage;
import org.openconcerto.utils.cc.IClosure;
 
import java.awt.Color;
import java.awt.GridBagConstraints;
62,6 → 63,7
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.FutureTask;
 
import javax.swing.Action;
import javax.swing.JFrame;
147,25 → 149,44
f.setTitle(comptaPropsConfiguration.getAppName() + " " + version + socTitle);
f.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
 
}
});
final FutureTask<?> showMainFrame = new FutureTask<Object>(new Runnable() {
@Override
public void run() {
FrameUtil.show(MainFrame.getInstance());
}
}, null);
ModuleManager.getInstance().invoke(new IClosure<ModuleManager>() {
@Override
public void executeChecked(ModuleManager input) {
// start modules before displaying the frame (e.g. avoid modifying a
// visible menu bar)
try {
ModuleManager.getInstance().startRequiredModules();
input.startRequiredModules();
} catch (Exception exn) {
// by definition we cannot continue without required modules
ExceptionHandler.die("Impossible de démarrer les modules requis", exn);
}
try {
ModuleManager.getInstance().startPreviouslyRunningModules();
input.startPreviouslyRunningModules();
} catch (Exception exn) {
// OK to continue without all modules started
ExceptionHandler.handle(f, "Impossible de démarrer les modules", exn);
// OK to start the application without all modules started
// but don't continue right away otherwise connexion panel will be
// closed and the popup with it
try {
ExceptionHandler.handle(NouvelleConnexionAction.this.connexionPanel, "Impossible de démarrer les modules", exn).getDialogFuture().get();
} catch (Exception e) {
e.printStackTrace();
}
}
 
FrameUtil.show(f);
SwingUtilities.invokeLater(showMainFrame);
}
});
initCache();
// don't close ConnexionPanel until the main frame is shown
showMainFrame.get();
} catch (Throwable e) {
ExceptionHandler.handle("Erreur de connexion", e);
}
231,6 → 252,9
}
 
private void initCache() {
final SQLBase baseSociete = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete();
// ensure consistent state before cache loading
baseSociete.getGraph();
Thread t = new Thread() {
@Override
public void run() {
244,7 → 268,6
CaisseCotisationSQLElement.getCaisseCotisation();
 
Ville.init(new NXDatabaseAccessor());
final SQLBase baseSociete = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete();
SQLBackgroundTableCache.getInstance().add(baseSociete.getTable("TAXE"), 600);
SQLBackgroundTableCache.getInstance().add(baseSociete.getTable("PREFS_COMPTE"), 600);
SQLBackgroundTableCache.getInstance().add(baseSociete.getTable("JOURNAL"), 600);
255,7 → 278,9
TaxeCache.getCache();
 
final UndefinedRowValuesCache UndefCache = UndefinedRowValuesCache.getInstance();
 
// TODO: 1 request to rules them all?
UndefCache.getDefaultRowValues(baseSociete.getTable("DEVIS"));
UndefCache.getDefaultRowValues(baseSociete.getTable("ETAT_DEVIS"));
UndefCache.getDefaultRowValues(baseSociete.getTable("ADRESSE"));
UndefCache.getDefaultRowValues(baseSociete.getTable("DEVIS_ELEMENT"));
UndefCache.getDefaultRowValues(baseSociete.getTable("CONTACT"));
/trunk/OpenConcerto/src/org/openconcerto/erp/injector/AchatAvoirSQLInjector.java
New file
0,0 → 1,30
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.erp.injector;
 
import org.openconcerto.sql.model.DBRoot;
import org.openconcerto.sql.model.SQLInjector;
import org.openconcerto.sql.model.SQLTable;
 
public class AchatAvoirSQLInjector extends SQLInjector {
public AchatAvoirSQLInjector(final DBRoot root) {
super(root, "SAISIE_ACHAT", "AVOIR_FOURNISSEUR");
final SQLTable tableFacture = getSource();
final SQLTable tableAvoir = getDestination();
map(tableFacture.getField("ID_FOURNISSEUR"), tableAvoir.getField("ID_FOURNISSEUR"));
 
map(tableFacture.getField("NUMERO_FACTURE"), tableAvoir.getField("NOM"));
// map(tableFacture.getField("INFOS"), tableAvoir.getField("INFOS"));
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/SheetXml.java
113,13 → 113,13
}
 
public void showPrintAndExport(final boolean showDocument, final boolean printDocument, boolean exportToPDF) {
showPrintAndExport(showDocument, printDocument, exportToPDF, Boolean.getBoolean("org.openconcerto.oo.useODSViewer"));
showPrintAndExport(showDocument, printDocument, exportToPDF, Boolean.getBoolean("org.openconcerto.oo.useODSViewer"), false);
}
 
/**
* Show, print and export the document to PDF. This method is synchronous
* */
public void showPrintAndExport(final boolean showDocument, final boolean printDocument, boolean exportToPDF, boolean useODSViewer) {
public void showPrintAndExport(final boolean showDocument, final boolean printDocument, boolean exportToPDF, boolean useODSViewer, boolean exportPDFSynch) {
 
final File generatedFile = getGeneratedFile();
final File pdfFile = getGeneratedPDFFile();
158,6 → 158,10
// un grand livre KD
if (exportToPDF) {
 
Thread t = new Thread(new Runnable() {
 
@Override
public void run() {
try {
SheetUtils.convert2PDF(doc, pdfFile);
 
164,11 → 168,6
} catch (Throwable e) {
ExceptionHandler.handle("Impossible de créer le PDF.", e);
}
 
Thread t = new Thread(new Runnable() {
 
@Override
public void run() {
List<StorageEngine> engines = StorageEngines.getInstance().getActiveEngines();
for (StorageEngine storageEngine : engines) {
if (storageEngine.isConfigured() && storageEngine.allowAutoStorage()) {
198,11 → 197,15
}
 
}
});
}, "convert and upload to pdf");
 
t.setDaemon(true);
t.start();
 
if (exportPDFSynch) {
t.join();
}
}
}
 
} catch (Exception e) {
e.printStackTrace();
328,12 → 331,12
File f = getGeneratedPDFFile();
if (!f.exists()) {
getOrCreateDocumentFile();
showPrintAndExport(false, false, true, useODSViewer);
showPrintAndExport(false, false, true, useODSViewer, true);
return f;
} else {
File fODS = getOrCreateDocumentFile();
if (fODS.lastModified() > f.lastModified()) {
showPrintAndExport(false, false, true, useODSViewer);
showPrintAndExport(false, false, true, useODSViewer, true);
}
return f;
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/SheetUtils.java
117,10 → 117,7
}
 
public static void convert2PDF(final OpenDocument doc, final File pdfFileToCreate) throws Exception {
 
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
assert (!SwingUtilities.isEventDispatchThread());
// Open the PDF document
Document document = new Document(PageSize.A4, 50, 50, 50, 50);
 
171,9 → 168,8
} catch (Exception originalExn) {
ExceptionHandler.handle("Impossible de créer le PDF " + pdfFileToCreate.getAbsolutePath(), originalExn);
}
 
}
});
}
 
/**
* Get a new file with an other extension
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/gestcomm/CourrierClientSheet.java
78,7 → 78,7
return m;
}
 
public String getFileName() {
protected String getName() {
return "Courrier_" + this.rowCourrier.getString("NUMERO");
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/gestcomm/RelanceSheet.java
117,7 → 117,7
SQLSelect sel = new SQLSelect(Configuration.getInstance().getBase());
sel.addSelect(this.rowRelance.getTable().getKey());
sel.setWhere(new Where(this.rowRelance.getTable().getField("ID_SAISIE_VENTE_FACTURE"), "=", this.rowRelance.getInt("ID_SAISIE_VENTE_FACTURE")));
sel.addFieldOrder(this.rowRelance.getTable().getField("DATE").getFullName());
sel.addFieldOrder(this.rowRelance.getTable().getField("DATE"));
@SuppressWarnings("unchecked")
List<Map<String, Number>> listResult = Configuration.getInstance().getBase().getDataSource().execute(sel.asString());
if (listResult != null && listResult.size() > 0) {
148,7 → 148,7
return true;
}
 
public String getFileName() {
protected String getName() {
return "Relance_" + this.rowRelance.getString("NUMERO");
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/gestcomm/EtatVentesXmlSheet.java
179,6 → 179,7
String nom = (String) obj[1];
ArticleVendu a = map.get(code + "##" + nom);
 
mValues.put("CODE", code);
mValues.put("NOM", nom);
mValues.put("QTE", a.qte);
mValues.put("T_PA", (a.ha / 100.0D));
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/OOXMLField.java
243,7 → 243,11
return result;
} else {
if (display == null || !display.equalsIgnoreCase("false")) {
if (cellSize != null && cellSize.trim().length() != 0 && o != null) {
return splitStringCell(cellSize, o.toString());
} else {
return (o == null) ? "" : o;
}
} else {
return "";
}
257,7 → 261,7
 
}
 
private String splitStringCell(String cellSize, String result) {
protected String splitStringCell(String cellSize, String result) {
try {
int nbCar = Integer.parseInt(cellSize);
result = StringUtils.splitString(result, nbCar);
345,7 → 349,7
// Retourne la date d'échéance
int idModeReglement = this.row.getInt("ID_MODE_REGLEMENT");
Date d = (Date) this.row.getObject("DATE");
return getDateEcheance(idModeReglement, d, this.elt.getAttributeValue("DatePattern"));
return getDateEcheance(idModeReglement, d, this.elt.getAttributeValue("datePattern"));
} else if (typeComp.equalsIgnoreCase("Jour")) {
int day = this.row.getInt(field);
stringValue = "le " + String.valueOf(day);
358,7 → 362,7
}
} else if (typeComp.equalsIgnoreCase("Date")) {
 
String datePattern = this.elt.getAttributeValue("DatePattern");
String datePattern = this.elt.getAttributeValue("datePattern");
if (datePattern == null || datePattern.trim().length() == 0) {
datePattern = "dd/MM/yyyy";
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/SpreadSheetCellValueContext.java
36,8 → 36,8
}
 
public void dump(PrintStream prt) {
prt.println("Row id: " + row.getID() + " table:" + row.getTable());
List<String> fields = new ArrayList<String>();
prt.println("Row id: " + row.getID() + " table: " + row.getTable().getName());
final List<String> fields = new ArrayList<String>();
fields.addAll(row.getFields());
Collections.sort(fields);
for (String field : fields) {
46,7 → 46,7
prt.println(row.getObject(field));
}
prt.println("Parameters:");
List<String> params = new ArrayList<String>();
final List<String> params = new ArrayList<String>();
params.addAll(map.keySet());
Collections.sort(params);
for (String param : params) {
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/OOgenerationXML.java
80,8 → 80,9
this.row = row;
}
 
public synchronized File createDocument(String templateId, File outputDirectory, final String expectedFileName, SQLRow rowLanguage) {
public synchronized File createDocument(String templateId, String typeTemplate, File outputDirectory, final String expectedFileName, SQLRow rowLanguage) {
final String langage = rowLanguage != null ? rowLanguage.getString("CHEMIN") : null;
 
cacheStyle.clear();
rowRefCache.clearCache();
rowsEltCache.clear();
119,10 → 120,10
SAXBuilder builder = new SAXBuilder();
try {
 
if (needAnnexe(templateId, row, rowLanguage)) {
if (needAnnexe(templateId, typeTemplate, row, rowLanguage)) {
// check if it exists
final String annexeTemplateId = templateId + "_annexe";
InputStream annexeStream = TemplateManager.getInstance().getTemplate(annexeTemplateId, langage, null);
InputStream annexeStream = TemplateManager.getInstance().getTemplate(annexeTemplateId, langage, typeTemplate);
if (annexeStream != null) {
templateId = annexeTemplateId;
System.err.println("modele With annexe " + templateId);
130,7 → 131,7
}
 
System.err.println("Using template id: " + templateId);
final InputStream xmlConfiguration = TemplateManager.getInstance().getTemplateConfiguration(templateId, langage, null);
final InputStream xmlConfiguration = TemplateManager.getInstance().getTemplateConfiguration(templateId, langage, typeTemplate);
 
Document doc = builder.build(xmlConfiguration);
 
141,7 → 142,7
List<Element> listElts = racine.getChildren("element");
 
// Création et génération du fichier OO
final InputStream template = TemplateManager.getInstance().getTemplate(templateId, langage, null);
final InputStream template = TemplateManager.getInstance().getTemplate(templateId, langage, typeTemplate);
 
final SpreadSheet spreadSheet = new ODPackage(template).getSpreadSheet();
try {
574,11 → 575,10
* @param id
*/
private void parseElementsXML(List<Element> elts, SQLRow row, SpreadSheet spreadSheet) {
SQLElement sqlElt = Configuration.getInstance().getDirectory().getElement(row.getTable());
final SQLElement sqlElt = Configuration.getInstance().getDirectory().getElement(row.getTable());
for (Element elt : elts) {
 
OOXMLElement OOElt = new OOXMLElement(elt, sqlElt, row.getID(), row, null, this.rowRefCache);
Object result = OOElt.getValue();
final OOXMLElement OOElt = new OOXMLElement(elt, sqlElt, row.getID(), row, null, this.rowRefCache);
final Object result = OOElt.getValue();
if (result != null) {
Object o = elt.getAttributeValue("sheet");
int sheet = (o == null) ? 0 : Integer.valueOf(o.toString().trim());
823,13 → 823,13
return mapStyleDef;
}
 
public boolean needAnnexe(String templateId, SQLRow row, SQLRow rowLanguage) {
public boolean needAnnexe(String templateId, String typeTemplate, SQLRow row, SQLRow rowLanguage) {
final String langage = rowLanguage != null ? rowLanguage.getString("CHEMIN") : null;
final SAXBuilder builder = new SAXBuilder();
try {
final InputStream xmlConfiguration = TemplateManager.getInstance().getTemplateConfiguration(templateId, langage, null);
final InputStream xmlConfiguration = TemplateManager.getInstance().getTemplateConfiguration(templateId, langage, typeTemplate);
final Document doc = builder.build(xmlConfiguration);
final InputStream template = TemplateManager.getInstance().getTemplate(templateId, langage, null);
final InputStream template = TemplateManager.getInstance().getTemplate(templateId, langage, typeTemplate);
 
final SpreadSheet spreadSheet = new ODPackage(template).getSpreadSheet();
 
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/AbstractSheetXml.java
58,7 → 58,7
templateId = getDefaultTemplateId();
}
final OOgenerationXML oXML = new OOgenerationXML(AbstractSheetXml.this.row);
AbstractSheetXml.this.generatedOpenDocumentFile = oXML.createDocument(templateId, getDocumentOutputDirectory(), getValidFileName(getName()), getRowLanguage());
AbstractSheetXml.this.generatedOpenDocumentFile = oXML.createDocument(templateId, getType(), getDocumentOutputDirectory(), getValidFileName(getName()), getRowLanguage());
 
} catch (Exception e) {
DEFAULT_HANDLER.uncaughtException(null, e);
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/DefaultLocalTemplateProvider.java
34,7 → 34,7
@Override
public File getTemplateFromLocalFile(String templateIdWithExtension, String language, String type) {
File file = getLocalFile(templateIdWithExtension, language, type);
if (!file.exists()) {
if (file != null && !file.exists()) {
file = getFile(templateIdWithExtension, language, type);
}
return file;
46,7 → 46,10
 
if (type != null) {
localPath = insertBeforeExtenstion(localPath, type);
if (localPath == null) {
return null;
}
}
 
if (language != null && language.trim().length() > 0) {
localPath = language + File.separatorChar + LOCAL + localPath;
63,7 → 66,10
 
if (type != null) {
path = insertBeforeExtenstion(path, type);
if (path == null) {
return null;
}
}
 
if (language != null && language.trim().length() > 0) {
path = language + File.separatorChar + path;
81,7 → 87,10
String path = "Configuration/Template/Default";
if (type != null) {
path = insertBeforeExtenstion(path, type);
if (path == null) {
return null;
}
}
if (language != null) {
path = language + '/' + path;
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/OOXMLElement.java
74,7 → 74,7
if (type.equalsIgnoreCase("DateEcheance")) {
int idModeReglement = row.getInt("ID_MODE_REGLEMENT");
Date d = (Date) row.getObject("DATE");
return getDateEcheance(idModeReglement, d, this.elt.getAttributeValue("DatePattern"));
return getDateEcheance(idModeReglement, d, this.elt.getAttributeValue("datePattern"));
}
 
final List<Element> eltFields = this.elt.getChildren("field");
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/OOXMLTableField.java
78,7 → 78,7
} else if (this.type.equalsIgnoreCase("DescriptifArticle")) {
value = getDescriptifArticle(this.row);
} else if (this.type.equalsIgnoreCase("DateEcheance")) {
value = getDateEcheance(this.row.getInt("ID_MODE_REGLEMENT"), (Date) this.row.getObject("DATE"), this.elt.getAttributeValue("DatePattern"));
value = getDateEcheance(this.row.getInt("ID_MODE_REGLEMENT"), (Date) this.row.getObject("DATE"), this.elt.getAttributeValue("datePattern"));
} else if (this.type.equalsIgnoreCase("MontantRevise")) {
value = getMontantRevise(this.row);
} else if (this.type.equalsIgnoreCase("Localisation")) {
86,7 → 86,11
} else {
OOXMLElement eltXml = new OOXMLElement(this.elt, this.sqlElt, this.id, this.row, this.rowLanguage, cache);
value = eltXml.getValue();
String cellSize = this.elt.getAttributeValue("cellSize");
if (cellSize != null && cellSize.trim().length() != 0 && value != null) {
value = splitStringCell(cellSize, value.toString());
}
}
 
return value;
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/OOgenerationListeXML.java
15,7 → 15,6
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.common.element.StyleSQLElement;
import org.openconcerto.erp.preferences.TemplateNXProps;
import org.openconcerto.openoffice.ODPackage;
import org.openconcerto.openoffice.spreadsheet.MutableCell;
import org.openconcerto.openoffice.spreadsheet.Sheet;
22,7 → 21,6
import org.openconcerto.openoffice.spreadsheet.SpreadSheet;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.task.config.ComptaBasePropsConfiguration;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.StreamUtils;
 
372,6 → 370,13
res = getValueOfComposant((Element) eltFields.get(0), mValues);
}
}
String attributeValueMaxChar = elt.getAttributeValue("maxChar");
if (attributeValueMaxChar != null ) {
int maxChar = Integer.valueOf(attributeValueMaxChar);
if (res != null && res.toString().length() > maxChar) {
res = res.toString().substring(0, maxChar);
}
}
return res;
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/AbstractJOOReportsSheet.java
56,8 → 56,34
*/
abstract protected Map createMap();
 
abstract public String getFileName();
abstract protected String getName();
 
public String getFileName() {
return getValidFileName(getName());
}
 
/**
* Remplace tous les caracteres non alphanumeriques (seul le _ est autorisé) par un -. Cela
* permet d'avoir toujours un nom de fichier valide.
*
* @param fileName nom du fichier à créer ex:FACTURE_2007/03/001
* @return un nom fichier valide ex:FACTURE_2007-03-001
*/
static String getValidFileName(String fileName) {
final StringBuffer result = new StringBuffer(fileName.length());
for (int i = 0; i < fileName.length(); i++) {
char ch = fileName.charAt(i);
 
// Si c'est un caractere alphanumerique
if (Character.isLetterOrDigit(ch) || (ch == '_') || (ch == ' ')) {
result.append(ch);
} else {
result.append('-');
}
}
return result.toString();
}
 
protected void init(String year, String templateId, String attributePrinter) {
this.year = year;
this.templateId = templateId;
/trunk/OpenConcerto/src/org/openconcerto/erp/generationDoc/AbstractLocalTemplateProvider.java
85,7 → 85,7
public static String insertBeforeExtenstion(String fileName, String text) {
final int index = fileName.lastIndexOf('.');
if (index < 0) {
throw new IllegalArgumentException("No extension found in fileName '" + fileName + "'");
return null;
}
if (index == 0) {
return fileName + text;
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtSaisieVenteFacture.java
24,6 → 24,7
 
import java.sql.SQLException;
import java.util.Date;
import java.util.List;
import java.util.Map;
 
// FIXME probleme lors de certaines generation tout reste figer
76,13 → 77,22
 
// Calcul des montants
PrixTTC prixTTC = new PrixTTC(((Long) saisieRow.getObject("T_TTC")).longValue());
// Total des acomptes déjà versés sur la facture
long montantAcompteTTC = 0;
PrixHT prixTVA = new PrixHT(((Long) saisieRow.getObject("T_TVA")).longValue());
PrixHT prixHT = new PrixHT(((Long) saisieRow.getObject("T_HT")).longValue());
PrixHT prixService = new PrixHT(((Long) saisieRow.getObject("T_SERVICE")).longValue());
 
int idCompteClient = clientRow.getInt("ID_COMPTE_PCE");
 
// iniatilisation des valeurs de la map
this.date = (Date) saisieRow.getObject("DATE");
this.nom = "Saisie Vente facture " + saisieRow.getObject("NUMERO").toString();
Boolean acompte = saisieRow.getBoolean("ACOMPTE");
if (acompte != null && acompte) {
this.nom = "Fact. acompte client" + saisieRow.getObject("NUMERO").toString();
} else {
this.nom = "Fact. vente " + saisieRow.getObject("NUMERO").toString();
}
this.mEcritures.put("DATE", this.date);
this.mEcritures.put("NOM", this.nom);
this.mEcritures.put("ID_JOURNAL", GenerationMvtSaisieVenteFacture.journal);
90,11 → 100,21
 
// on calcule le nouveau numero de mouvement
if (this.idMvt == 1) {
getNewMouvement(GenerationMvtSaisieVenteFacture.source, this.idSaisieVenteFacture, 1, "Saisie vente facture " + saisieRow.getObject("NUMERO").toString());
getNewMouvement(GenerationMvtSaisieVenteFacture.source, this.idSaisieVenteFacture, 1, this.nom);
} else {
this.mEcritures.put("ID_MOUVEMENT", Integer.valueOf(this.idMvt));
SQLRowValues rowValsPiece = mvtTable.getRow(idMvt).getForeign("ID_PIECE").asRowValues();
rowValsPiece.put("NOM", this.nom);
try {
rowValsPiece.update();
} catch (SQLException exn) {
// TODO Bloc catch auto-généré
exn.printStackTrace();
}
}
 
// On génére les ecritures si la facture n'est pas un acompte
if (acompte == null || !acompte) {
// generation des ecritures + maj des totaux du compte associe
int idCompteVenteService = saisieRow.getInt("ID_COMPTE_PCE_SERVICE");
if (idCompteVenteService <= 1) {
152,8 → 172,8
}
 
// compte TVA
int idCompteTVA = rowPrefsCompte.getInt("ID_COMPTE_PCE_TVA_VENTE");
if (prixTVA.getLongValue() > 0) {
int idCompteTVA = rowPrefsCompte.getInt("ID_COMPTE_PCE_TVA_VENTE");
if (idCompteTVA <= 1) {
try {
idCompteTVA = ComptePCESQLElement.getIdComptePceDefault("TVACollectee");
162,7 → 182,7
}
}
 
Map<Integer, Long> m = getMultiTVAFromRow(saisieRow, saisieVFTable.getTable("SAISIE_VENTE_FACTURE_ELEMENT"), true);
Map<Integer, Long> m = getMultiTVAFromRow(saisieRow, saisieVFTable.getTable("SAISIE_VENTE_FACTURE_ELEMENT"), true, prixHT, ((Long) (saisieRow.getObject("REMISE_HT"))).longValue());
long allTaxe = 0;
for (Integer i : m.keySet()) {
Long l = m.get(i);
188,7 → 208,7
 
}
// compte Clients
int idCompteClient = clientRow.getInt("ID_COMPTE_PCE");
 
if (idCompteClient <= 1) {
idCompteClient = rowPrefsCompte.getInt("ID_COMPTE_PCE_CLIENT");
if (idCompteClient <= 1) {
204,10 → 224,76
this.mEcritures.put("CREDIT", Long.valueOf(0));
ajoutEcriture();
 
// TODO Gestion des factures d'acomptes
// Solde des acomptes
// List<SQLRow> rowsAcompte =
// saisieRow.getReferentRows(saisieVFTable.getField("ID_SAISIE_VENTE_FACTURE_ACOMPTE"));
// if (rowsAcompte != null && rowsAcompte.size() > 0) {
// // Compte acompte
// int idCompteAcompteClient = ComptePCESQLElement.getId("4191",
// "Clients - Avances et acomptes reçus sur commandes");
// int idTVAAcompte = ComptePCESQLElement.getId("44587",
// "Taxes sur le chiffre d'affaire à régulariser ou en attente");
// for (SQLRow sqlRow : rowsAcompte) {
// long acompteTTC = sqlRow.getLong("T_TTC");
// long acompteHT = sqlRow.getLong("T_HT");
// this.mEcritures.put("ID_COMPTE_PCE", Integer.valueOf(idCompteAcompteClient));
// this.mEcritures.put("DEBIT", acompteTTC);
// this.mEcritures.put("CREDIT", Long.valueOf(0));
// ajoutEcriture();
// this.mEcritures.put("ID_COMPTE_PCE", Integer.valueOf(idCompteClient));
// this.mEcritures.put("DEBIT", Long.valueOf(0));
// this.mEcritures.put("CREDIT", acompteTTC);
// ajoutEcriture();
//
// montantAcompteTTC += acompteTTC;
//
// long tva = acompteTTC - acompteHT;
// if (tva > 0) {
//
//
// this.mEcritures.put("ID_COMPTE_PCE", Integer.valueOf(idTVAAcompte));
// this.mEcritures.put("DEBIT", Long.valueOf(0));
// this.mEcritures.put("CREDIT", Long.valueOf(tva));
// ajoutEcriture();
//
// Map<Integer, Long> m = getMultiTVAFromRow(saisieRow,
// saisieVFTable.getTable("SAISIE_VENTE_FACTURE_ELEMENT"), true);
// long allTaxe = 0;
// for (Integer i : m.keySet()) {
// Long l = m.get(i);
// if (l != null && l > 0) {
// // FIXME
// int idCpt = i;
// if (idCpt <= 1) {
// idCpt = idCompteTVA;
// }
// this.mEcritures.put("ID_COMPTE_PCE", Integer.valueOf(idCpt));
// this.mEcritures.put("DEBIT", Long.valueOf(0));
// this.mEcritures.put("CREDIT", Long.valueOf(l));
// ajoutEcriture();
// allTaxe += l;
// }
// }
// if (allTaxe < prixTVA.getLongValue()) {
// this.mEcritures.put("ID_COMPTE_PCE", Integer.valueOf(idCompteTVA));
// this.mEcritures.put("DEBIT", Long.valueOf(0));
// this.mEcritures.put("CREDIT", Long.valueOf(prixTVA.getLongValue() - allTaxe));
// ajoutEcriture();
// }
//
// this.mEcritures.put("ID_COMPTE_PCE", Integer.valueOf(compteDebitTvaAcompte));
// this.mEcritures.put("DEBIT", Long.valueOf(tva));
// this.mEcritures.put("CREDIT", Long.valueOf(0));
// ajoutEcriture();
// }
// }
// }
}
// Génération du reglement
SQLRow modeRegl = saisieRow.getForeignRow("ID_MODE_REGLEMENT");
final SQLRow typeRegRow = modeRegl.getForeignRow("ID_TYPE_REGLEMENT");
String label = "Saisie Vente facture " + saisieRow.getObject("NUMERO").toString() + " (" + typeRegRow.getString("NOM") + ")";
String label = this.nom + " (" + typeRegRow.getString("NOM") + ")";
int idAvoir = saisieRow.getInt("ID_AVOIR_CLIENT");
if (idAvoir > 1) {
// SQLRow avoirRow = base.getTable("AVOIR_CLIENT").getRow(idAvoir);
214,6 → 300,7
long l = ((Number) saisieRow.getObject("T_AVOIR_TTC")).longValue();
prixTTC = new PrixTTC(((Long) saisieRow.getObject("T_TTC")).longValue() - l);
}
prixTTC = new PrixTTC(prixTTC.getLongValue() - montantAcompteTTC);
if (prixTTC.getLongValue() > 0) {
new GenerationReglementVenteNG(label, clientRow, prixTTC, this.date, modeRegl, saisieRow, mvtTable.getRow(idMvt));
}
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtTicketCaisse.java
122,7 → 122,7
}
 
Map<Integer, Long> m = getMultiTVAFromRow(GenerationMvtTicketCaisse.this.rowTicket, GenerationMvtTicketCaisse.this.rowTicket.getTable().getTable("SAISIE_VENTE_FACTURE_ELEMENT"),
true);
true, prixHT, 0);
long allTaxe = 0;
for (Integer i : m.keySet()) {
Long l = m.get(i);
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationEcritures.java
14,9 → 14,11
package org.openconcerto.erp.generationEcritures;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.model.PrixHT;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLBase;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
30,6 → 32,7
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
 
import javax.swing.SwingUtilities;
 
322,7 → 325,7
return 1;
}
 
protected Map<Integer, Long> getMultiTVAFromRow(SQLRow row, SQLTable foreign, boolean vente) {
protected Map<Integer, Long> getMultiTVAFromRow(SQLRow row, SQLTable foreign, boolean vente, PrixHT totalHt, long remiseHT) {
List<SQLRow> rows = row.getReferentRows(foreign);
 
// Total HT par TVA
338,6 → 341,42
}
}
 
if (row.getTable().contains("ID_TAXE_PORT")) {
long port = row.getLong("PORT_HT");
if (port > 0) {
SQLRow taxePort = row.getForeignRow("ID_TAXE_PORT");
if (taxePort != null && !taxePort.isUndefined()) {
 
// Total TVA
if (mapTaxeHT.get(taxePort) == null) {
mapTaxeHT.put(taxePort, port);
} else {
Long l = mapTaxeHT.get(taxePort);
mapTaxeHT.put(taxePort, l + port);
}
}
}
}
// Déduction de la remise pour la TVA
long totalHTAvantRemise = totalHt.getLongValue() + remiseHT;
long remiseToApply = remiseHT;
if (remiseToApply > 0) {
Set<SQLRow> setHtTVA = mapTaxeHT.keySet();
int i = 0;
for (SQLRow rowA : mapTaxeHT.keySet()) {
Long ht = mapTaxeHT.get(rowA);
i++;
if (i == setHtTVA.size()) {
mapTaxeHT.put(rowA, ht - remiseToApply);
} else {
// Prorata
long r = new BigDecimal(ht).divide(new BigDecimal(totalHTAvantRemise), MathContext.DECIMAL128).multiply(new BigDecimal(remiseHT)).setScale(0, BigDecimal.ROUND_HALF_UP).longValue();
mapTaxeHT.put(rowA, ht - r);
remiseToApply -= r;
}
}
}
 
Map<Integer, Long> map = new HashMap<Integer, Long>();
for (SQLRow sqlRow : mapTaxeHT.keySet()) {
BigDecimal d = new BigDecimal(sqlRow.getFloat("TAUX"));
/trunk/OpenConcerto/src/org/openconcerto/erp/generationEcritures/GenerationMvtAvoirClient.java
153,7 → 153,7
}
}
 
Map<Integer, Long> m = getMultiTVAFromRow(avoirRow, avoirClientTable.getTable("AVOIR_CLIENT_ELEMENT"), true);
Map<Integer, Long> m = getMultiTVAFromRow(avoirRow, avoirClientTable.getTable("AVOIR_CLIENT_ELEMENT"), true, prixHT, 0);
long allTaxe = 0;
for (Integer i : m.keySet()) {
Long l = m.get(i);
/trunk/OpenConcerto/src/org/openconcerto/erp/core/reports/history/ui/HistoriqueClientFrame.java
22,6 → 22,7
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.users.rights.JListSQLTablePanel;
 
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
64,7 → 65,7
map.put(b.getTable("DEVIS_ELEMENT"), b.getTable("DEVIS_ELEMENT").getField("ID_DEVIS"));
 
final HistoriqueClientBilanPanel bilanPanel = new HistoriqueClientBilanPanel();
this.listPanel = new ListeHistoriquePanel("Clients", b.getTable("CLIENT"), mapList, bilanPanel, map);
this.listPanel = new ListeHistoriquePanel("Clients", JListSQLTablePanel.createComboRequest(b.getTable("CLIENT"), true), mapList, bilanPanel, map);
 
this.listPanel.addListenerTable(new TableModelListener() {
public void tableChanged(TableModelEvent arg0) {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/reports/history/ui/ListeHistoriquePanel.java
33,11 → 33,13
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.request.ComboSQLRequest;
import org.openconcerto.sql.users.rights.JListSQLTablePanel;
import org.openconcerto.sql.view.IListPanel;
import org.openconcerto.sql.view.ListeAddPanel;
import org.openconcerto.sql.view.list.IListe;
import org.openconcerto.sql.view.list.ITableModel;
import org.openconcerto.sql.view.list.SQLTableModelSourceOnline;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.FrameUtil;
import org.openconcerto.utils.cc.ITransformer;
173,14 → 175,19
}
};
 
public ListeHistoriquePanel(final String title, final SQLTable tableList, Map<String, List<String>> listTableOnglet, JPanel panelBottom, Map<SQLTable, SQLField> listFieldMap) {
this(title, tableList, listTableOnglet, panelBottom, listFieldMap, "Tous");
public ListeHistoriquePanel(final String title, final ComboSQLRequest req, Map<String, List<String>> listTableOnglet, JPanel panelBottom, Map<SQLTable, SQLField> listFieldMap) {
this(title, req, listTableOnglet, panelBottom, listFieldMap, "Tous");
}
 
public ListeHistoriquePanel(final String title, final ComboSQLRequest req, Map<String, List<String>> listTableOnglet, JPanel panelBottom, Map<SQLTable, SQLField> listFieldMap,
String undefinedLabel) {
this(title, req, listTableOnglet, panelBottom, listFieldMap, undefinedLabel, false);
}
 
// TODO verifier que les tables contiennent bien la clef etrangere
/**
* @param title titre de la JList
* @param tableList table à afficher la JList
* @param req table à afficher la JListSQLTablePanel
* @param listTableOnglet liste des tables à afficher
* @param panelBottom panel à afficher en bas de la frame
* @param listFieldMap jointure d'une table pour utiliser le filtre si la table ne contient pas
188,7 → 195,8
* @param undefinedLabel label pour l'indéfini permettant de tout sélectionner, null si
* l'undefined n'est pas à inclure.
*/
public ListeHistoriquePanel(final String title, final SQLTable tableList, Map<String, List<String>> listTableOnglet, JPanel panelBottom, Map<SQLTable, SQLField> listFieldMap, String undefinedLabel) {
public ListeHistoriquePanel(final String title, final ComboSQLRequest req, Map<String, List<String>> listTableOnglet, JPanel panelBottom, Map<SQLTable, SQLField> listFieldMap,
String undefinedLabel, final boolean sourceWithOutTransformer) {
super();
this.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
249,7 → 257,11
};
 
} else {
liste = new ListeAddPanel(elt, new IListe(elt.createTableSource(Where.FALSE)), "historique-" + title) {
SQLTableModelSourceOnline createTableSource = elt.createTableSource(Where.FALSE);
if (sourceWithOutTransformer) {
createTableSource.getReq().setSelectTransf(null);
}
liste = new ListeAddPanel(elt, new IListe(createTableSource), "historique-" + title) {
@Override
protected void handleAction(JButton source, ActionEvent evt) {
if (source == this.buttonAjouter) {
306,11 → 318,9
}
 
// Left Panel
SQLElement e = Configuration.getInstance().getDirectory().getElement(tableList);
this.undefinedLabel = undefinedLabel;
this.jListePanel = new JListSQLTablePanel(req, undefinedLabel);
 
List<String> fields = getListSQLField(e.getComboRequest().getFields());
this.jListePanel = new JListSQLTablePanel(tableList, fields, undefinedLabel);
 
// Right panel
JPanel rightPanel = new JPanel();
rightPanel.setLayout(new GridBagLayout());
/trunk/OpenConcerto/src/org/openconcerto/erp/core/reports/history/ui/HistoriqueClientBilanPanel.java
113,7 → 113,7
selVF.addSelect(tableVF.getField("T_HT"), "SUM");
 
if (idClient > 1) {
selVF.setWhere("SAISIE_VENTE_FACTURE.ID_CLIENT", "=", idClient);
selVF.setWhere(tableVF.getField("ID_CLIENT"), "=", idClient);
}
final String req = selVF.asString();
// System.err.println(req);
125,7 → 125,7
selVC.addSelect(tableVC.getField("MONTANT_HT"), "SUM");
 
if (idClient > 1) {
selVC.setWhere("SAISIE_VENTE_COMPTOIR.ID_CLIENT", "=", idClient);
selVC.setWhere(tableVC.getField("ID_CLIENT"), "=", idClient);
}
final String reqVC = selVC.asString();
// System.err.println(reqVC);
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/supplier/action/NouvelHistoriqueListeFournAction.java
21,6 → 21,7
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLBase;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.users.rights.JListSQLTablePanel;
 
import java.util.Arrays;
import java.util.HashMap;
48,7 → 49,7
mapList.put("Chèques émis", Arrays.asList("CHEQUE_FOURNISSEUR"));
 
final HistoriqueFournBilanPanel panelBilan = new HistoriqueFournBilanPanel();
final ListeHistoriquePanel listHistoriquePanel = new ListeHistoriquePanel("Fournisseurs", b.getTable("FOURNISSEUR"), mapList, panelBilan, null);
final ListeHistoriquePanel listHistoriquePanel = new ListeHistoriquePanel("Fournisseurs", JListSQLTablePanel.createComboRequest(b.getTable("FOURNISSEUR"), true), mapList, panelBilan, null);
 
listHistoriquePanel.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/supplier/ui/HistoriqueFournBilanPanel.java
79,7 → 79,7
SQLSelect selNb = new SQLSelect(base);
selNb.addSelectStar(tableC);
if (idFournisseur > 1) {
selNb.setWhere(tableC.getName() + ".ID_FOURNISSEUR", "=", idFournisseur);
selNb.setWhere(tableC.getField("ID_FOURNISSEUR"), "=", idFournisseur);
}
List lnb = (List) base.getDataSource().execute(selNb.asString(), new ArrayListHandler());
final int nombreCheque = (lnb == null) ? 0 : lnb.size();
127,7 → 127,7
SQLSelect selNb = new SQLSelect(base);
selNb.addSelectStar(tableC);
if (idFournisseur > 1) {
selNb.setWhere(tableC.getName() + ".ID_FOURNISSEUR", "=", idFournisseur);
selNb.setWhere(tableC.getField("ID_FOURNISSEUR"), "=", idFournisseur);
}
List lnb = (List) base.getDataSource().execute(selNb.asString(), new ArrayListHandler());
final int nombreAchat = (lnb == null) ? 0 : lnb.size();
161,7 → 161,7
sel.addSelect(f, "SUM");
 
if (idFourn > 1) {
sel.setWhere(f.getTable().getName() + ".ID_FOURNISSEUR", "=", idFourn);
sel.setWhere(f.getTable().getField("ID_FOURNISSEUR"), "=", idFourn);
}
List l = (List) f.getTable().getBase().getDataSource().execute(sel.asString(), new ArrayListHandler());
 
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/order/element/SaisieAchatSQLElement.java
13,13 → 13,22
package org.openconcerto.erp.core.supplychain.order.element;
 
import org.openconcerto.erp.config.Gestion;
import org.openconcerto.erp.core.common.element.ComptaSQLConfElement;
import org.openconcerto.erp.core.supplychain.credit.component.AvoirFournisseurSQLComponent;
import org.openconcerto.erp.core.supplychain.order.component.SaisieAchatSQLComponent;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLComponent;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLInjector;
import org.openconcerto.sql.view.EditFrame;
 
import java.util.ArrayList;
import java.util.List;
 
import javax.swing.ImageIcon;
import javax.swing.JFrame;
 
public class SaisieAchatSQLElement extends ComptaSQLConfElement {
 
public SaisieAchatSQLElement() {
65,4 → 74,19
protected String createCode() {
return createCodeFromPackage() + ".purchase";
}
 
public void transfertAvoir(int idFacture) {
final SQLElement elt = Configuration.getInstance().getDirectory().getElement("AVOIR_FOURNISSEUR");
final EditFrame editAvoirFrame = new EditFrame(elt);
editAvoirFrame.setIconImage(new ImageIcon(Gestion.class.getResource("frameicon.png")).getImage());
 
final AvoirFournisseurSQLComponent comp = (AvoirFournisseurSQLComponent) editAvoirFrame.getSQLComponent();
final SQLInjector inject = SQLInjector.getInjector(this.getTable(), elt.getTable());
comp.select(inject.createRowValuesFrom(idFacture));
 
editAvoirFrame.pack();
editAvoirFrame.setState(JFrame.NORMAL);
editAvoirFrame.setVisible(true);
 
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/order/component/SaisieAchatSQLComponent.java
609,4 → 609,5
this.select(injector.createRowValuesFrom(id));
}
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/supplychain/order/component/CommandeSQLComponent.java
20,6 → 20,7
import org.openconcerto.erp.core.common.ui.AbstractVenteArticleItemTable;
import org.openconcerto.erp.core.common.ui.DeviseField;
import org.openconcerto.erp.core.common.ui.TotalPanel;
import org.openconcerto.erp.core.finance.tax.model.TaxeCache;
import org.openconcerto.erp.core.supplychain.order.element.CommandeSQLElement;
import org.openconcerto.erp.core.supplychain.order.ui.CommandeItemTable;
import org.openconcerto.erp.generationDoc.gestcomm.CommandeXmlSheet;
34,12 → 35,12
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.request.ComboSQLRequest;
import org.openconcerto.sql.sqlobject.ElementComboBox;
import org.openconcerto.sql.sqlobject.JUniqueTextField;
import org.openconcerto.sql.sqlobject.SQLRequestComboBox;
import org.openconcerto.sql.users.UserManager;
import org.openconcerto.sql.view.EditFrame;
import org.openconcerto.ui.AutoHideListener;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.FormLayouter;
import org.openconcerto.ui.JDate;
161,7 → 162,7
c.fill = GridBagConstraints.HORIZONTAL;
final ElementComboBox boxContactFournisseur = new ElementComboBox();
final SQLElement contactElement = Configuration.getInstance().getDirectory().getElement("CONTACT_FOURNISSEUR");
boxContactFournisseur.init(contactElement, new ComboSQLRequest(contactElement.getComboRequest()));
boxContactFournisseur.init(contactElement, contactElement.getComboRequest(true));
this.add(boxContactFournisseur, c);
this.addView(boxContactFournisseur, "ID_CONTACT_FOURNISSEUR", REQ);
 
504,18 → 505,28
}
 
DeviseField textPortHT = new DeviseField();
ElementComboBox comboTaxePort = new ElementComboBox();
 
if (getTable().contains("PORT_HT")) {
addRequiredSQLObject(textPortHT, "PORT_HT");
final JPanel panelPoids = new JPanel();
 
panelPoids.add(new JLabel(getLabelFor("PORT_HT")), c);
 
// textPortHT.setEnabled(false);
final JPanel panelPoids = new JPanel(new GridBagLayout());
GridBagConstraints cPort = new DefaultGridBagConstraints();
cPort.gridx = 0;
cPort.weightx = 0;
panelPoids.add(new JLabel(getLabelFor("PORT_HT")), cPort);
textPortHT.setHorizontalAlignment(JTextField.RIGHT);
// textPortHT.setDisabledTextColor(Color.BLACK);
cPort.gridx++;
cPort.weightx = 1;
panelPoids.add(textPortHT, cPort);
 
panelPoids.add(textPortHT, c);
cPort.gridy++;
cPort.gridx = 0;
cPort.weightx = 0;
addRequiredSQLObject(comboTaxePort, "ID_TAXE_PORT");
panelPoids.add(new JLabel(getLabelFor("ID_TAXE_PORT")), cPort);
cPort.gridx++;
cPort.weightx = 0;
panelPoids.add(comboTaxePort, cPort);
 
c.gridx++;
c.gridy = 0;
546,7 → 557,8
 
addRequiredSQLObject(fieldTTC, "T_TTC");
addRequiredSQLObject(fieldService, "T_SERVICE");
final TotalPanel totalTTC = new TotalPanel(this.table, fieldHT, fieldTVA, fieldTTC, textPortHT, textRemiseHT, fieldService, null, fieldDevise, null, null);
final TotalPanel totalTTC = new TotalPanel(this.table, fieldHT, fieldTVA, fieldTTC, textPortHT, textRemiseHT, fieldService, null, fieldDevise, null, null,
(getTable().contains("ID_TAXE_PORT") ? comboTaxePort : null));
 
c.gridx++;
c.gridy--;
559,6 → 571,12
 
panel.add(totalTTC, c);
 
c.gridy += 3;
c.gridheight = 2;
c.fill = GridBagConstraints.NONE;
c.anchor = GridBagConstraints.EAST;
panel.add(getModuleTotalPanel(), c);
 
table.getModel().addTableModelListener(new TableModelListener() {
 
public void tableChanged(TableModelEvent e) {
580,6 → 598,15
}
});
 
comboTaxePort.addValueListener(new PropertyChangeListener() {
 
@Override
public void propertyChange(PropertyChangeEvent evt) {
// TODO Raccord de méthode auto-généré
totalTTC.updateTotal();
}
});
 
textRemiseHT.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
totalTTC.updateTotal();
596,6 → 623,11
return panel;
}
 
protected JPanel getModuleTotalPanel() {
 
return AutoHideListener.listen(new JPanel());
}
 
public int insert(SQLRow order) {
 
int idCommande = getSelectedID();
717,6 → 749,10
rowVals.put("T_TTC", Long.valueOf(0));
rowVals.put("NUMERO", NumerotationAutoSQLElement.getNextNumero(CommandeSQLElement.class));
 
if (getTable().contains("ID_TAXE_PORT")) {
rowVals.put("ID_TAXE_PORT", TaxeCache.getCache().getIdFromTaux(19.6F));
}
 
return rowVals;
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/element/AnalytiqueSQLElement.java
133,8 → 133,8
// SELECT ID, NOM FROM AXE
SQLBase base = getTable().getBase();
SQLSelect sel = new SQLSelect(base);
sel.addSelect("AXE_ANALYTIQUE.ID");
sel.addSelect("AXE_ANALYTIQUE.NOM");
sel.addSelect(getTable().getKey());
sel.addSelect(getTable().getField("NOM"));
sel.addRawOrder("AXE_ANALYTIQUE.NOM");
String req = sel.asString();
 
429,7 → 429,7
SQLSelect selAssoc = new SQLSelect(base);
selAssoc.addSelect(assocTable.getField("ID"));
selAssoc.addSelect(assocTable.getField("ID_COMPTE_PCE"));
selAssoc.setWhere("ASSOCIATION_COMPTE_ANALYTIQUE.ID_AXE_ANALYTIQUE", "=", ((Axe) this.axes.get(axeSelect)).getId());
selAssoc.setWhere(assocTable.getField("ID_AXE_ANALYTIQUE"), "=", ((Axe) this.axes.get(axeSelect)).getId());
 
String reqAssoc = selAssoc.asString();
Object obAssoc = getTable().getBase().getDataSource().execute(reqAssoc, new ArrayListHandler());
558,7 → 558,7
SQLSelect selAssoc = new SQLSelect(base);
selAssoc.addSelect(assocTable.getField("ID"));
selAssoc.addSelect(assocTable.getField("ID_COMPTE_PCE"));
selAssoc.setWhere("ASSOCIATION_COMPTE_ANALYTIQUE.ID_REPARTITION_ANALYTIQUE", "=", rep.getId());
selAssoc.setWhere(assocTable.getField("ID_REPARTITION_ANALYTIQUE"), "=", rep.getId());
 
String reqAssoc = selAssoc.asString();
Object obAssoc = getTable().getBase().getDataSource().execute(reqAssoc, new ArrayListHandler());
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/element/ComptePCESQLElement.java
38,6 → 38,7
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
 
import javax.swing.JCheckBox;
import javax.swing.JLabel;
70,7 → 71,8
public SQLComponent createComponent() {
return new BaseSQLComponent(this) {
 
private boolean isCompteValid = false;
// private boolean isCompteValid = false;
private ValidState compteNumeroValidState = ValidState.getTrueInstance();
private JUniqueTextField textNumero = new JUniqueTextField(7);
 
@Override
106,41 → 108,10
@Override
public void update(DocumentEvent e) {
 
// On verifie que le numero est correct compris qu'il commence par 1-8
if (textNumero.getText().trim().length() > 0) {
if ((textNumero.getText().trim().charAt(0) < '1') || (textNumero.getText().trim().charAt(0) > '8')) {
System.err.println("Numero de compte incorrect");
isCompteValid = false;
} else {
isCompteValid = true;
}
// On verifie que le numero est correct
compteNumeroValidState = getCompteNumeroValidState(textNumero.getText());
 
// else {
//
// // on verifie que le numero n'existe pas deja
// SQLSelect selCompte = new SQLSelect(getTable().getBase());
// selCompte.addSelect(getTable().getField("NUMERO"));
//
// selCompte.setWhere("COMPTE_PCE.NUMERO", "=",
// textNumero.getText().trim());
//
// String reqCompte = selCompte.asString();
// Object obRep =
// getTable().getBase().getDataSource().execute(reqCompte, new
// ArrayListHandler());
//
// List tmpCpt = (List) obRep;
//
// System.err.println("REQUEST :: " + reqCompte);
// System.err.println("nb Same :: " + tmpCpt.size());
//
// isCompteValid = tmpCpt.size() == 0;
// }
} else {
isCompteValid = false;
}
fireValidChange();
System.err.println("Compte Valid " + isCompteValid);
}
});
 
199,11 → 170,30
 
@Override
public synchronized ValidState getValidState() {
return super.getValidState().and(ValidState.createCached(this.isCompteValid, "Le numéro de compte ne commence pas par un chiffre entre 1 et 8"));
return super.getValidState().and(this.compteNumeroValidState);
}
};
}
 
public ValidState getCompteNumeroValidState(String text) {
 
if (text.trim().length() > 0) {
if ((text.trim().charAt(0) < '1') || (text.trim().charAt(0) > '8')) {
// System.err.println("Numero de compte incorrect");
 
return ValidState.create(false, "Le numéro de compte ne commence pas par un chiffre entre 1 et 8");
} else if (text.endsWith(" ")) {
return ValidState.create(false, "Le numéro de compte ne doit pas se terminer par un espace");
} else {
Pattern p = Pattern.compile("^\\d(\\w)+$");
return ValidState.create(p.matcher(text).matches(), "Le numéro de compte n'est pas correct.");
}
 
}
return ValidState.getTrueInstance();
 
}
 
@Override
protected void archive(SQLRow row, boolean cutLinks) throws SQLException {
// on verifie qu'aucune ecriture n'est asssociée à ce compte
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/element/EcritureSQLElement.java
325,7 → 325,7
 
SQLSelect selectFils = new SQLSelect(base);
selectFils.addSelect(tableMvt.getField("ID"));
selectFils.setWhere("MOUVEMENT.ID_MOUVEMENT_PERE", "=", idMvtPere);
selectFils.setWhere(tableMvt.getField("ID_MOUVEMENT_PERE"), "=", idMvtPere);
 
List l = (List) base.getDataSource().execute(selectFils.asString(), new ArrayListHandler());
 
456,7 → 456,7
 
SQLSelect selectFils = new SQLSelect(base);
selectFils.addSelect(tableMvt.getField("ID"));
selectFils.setWhere("MOUVEMENT.ID_MOUVEMENT_PERE", "=", idMvtPere);
selectFils.setWhere(tableMvt.getField("ID_MOUVEMENT_PERE"), "=", idMvtPere);
 
List l = (List) base.getDataSource().execute(selectFils.asString(), new ArrayListHandler());
 
502,7 → 502,7
// on recupere l'ensemble des ecritures associées au mouvement
SQLSelect selEcritures = new SQLSelect(base);
selEcritures.addSelect(tableEcriture.getField("ID"));
selEcritures.setWhere("ECRITURE.ID_MOUVEMENT", "=", idMvt);
selEcritures.setWhere(tableEcriture.getField("ID_MOUVEMENT"), "=", idMvt);
 
List l = (List) base.getDataSource().execute(selEcritures.asString(), new ArrayListHandler());
for (int i = 0; i < l.size(); i++) {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/report/GrandLivreSheetXML.java
66,11 → 66,6
public static String TEMPLATE_ID = "GrandLivre";
public static String TEMPLATE_PROPERTY_NAME = "LocationGrandLivre";
 
public static void setSize(int debut, int fin) {
debutFill = debut;
endFill = fin;
}
 
@Override
public String getDefaultTemplateId() {
return TEMPLATE_ID;
196,9 → 191,9
}
 
sel.setWhere(w);
sel.addRawOrder("\"ECRITURE\".\"COMPTE_NUMERO\"");
sel.addRawOrder("\"ECRITURE\".\"DATE\"");
sel.addRawOrder("\"MOUVEMENT\".\"NUMERO\"");
sel.addFieldOrder(tableEcriture.getField("COMPTE_NUMERO"));
sel.addFieldOrder(tableEcriture.getField("DATE"));
sel.addFieldOrder(tableMvt.getField("NUMERO"));
System.err.println(sel.asString());
return sel;
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/report/JournauxSheetXML.java
New file
0,0 → 1,218
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.erp.core.finance.accounting.report;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.generationDoc.AbstractListeSheetXml;
import org.openconcerto.erp.preferences.PrinterNXProps;
import org.openconcerto.erp.rights.ComptaUserRight;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLRowValuesListFetcher;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.users.UserManager;
import org.openconcerto.utils.GestionDevise;
import org.openconcerto.utils.cc.ITransformer;
 
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
public class JournauxSheetXML extends AbstractListeSheetXml {
 
private final static SQLTable tableEcriture = base.getTable("ECRITURE");
protected final static SQLTable tableJournal = base.getTable("JOURNAL");
private final static SQLTable tableMvt = base.getTable("MOUVEMENT");
protected final static SQLTable tableCompte = base.getTable("COMPTE_PCE");
public final static int MODEALL = 1;
public final static int MODELETTREE = 2;
public final static int MODENONLETTREE = 3;
 
private final static DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM);
private final static DateFormat dateFormatEcr = DateFormat.getDateInstance(DateFormat.SHORT);
protected Date dateDu, dateAu;
protected int id;
protected int lettrage;
private String compteDeb, compteEnd;
 
public static String TEMPLATE_ID = "Journaux";
public static String TEMPLATE_PROPERTY_NAME = "LocationJournaux";
 
private SQLRow rowSociete = ((ComptaPropsConfiguration) Configuration.getInstance()).getRowSociete();
 
@Override
public String getDefaultTemplateId() {
return TEMPLATE_ID;
}
 
Date date;
 
@Override
public String getName() {
if (this.date == null) {
this.date = new Date();
}
return "Journal" + date.getTime();
}
 
public JournauxSheetXML(int id, Date du, Date au, int lettrage, String compteDeb, String compteEnd) {
super();
Calendar cal = Calendar.getInstance();
cal.setTime(au);
this.printer = PrinterNXProps.getInstance().getStringProperty("JournauxPrinter");
this.dateAu = au;
this.dateDu = du;
this.id = id;
this.lettrage = lettrage;
this.compteDeb = compteDeb;
this.compteEnd = compteEnd;
}
 
protected void makeEntete(Map<String, Object> line, String nomJournal) {
line.put("TITRE_1", "Journal " + nomJournal + " - " + rowSociete.getObject("TYPE") + " " + rowSociete.getObject("NOM"));
line.put("TITRE_2", "Edition du " + dateFormat.format(new Date()) + " Période du " + dateFormatEcr.format(this.dateDu) + " au " + dateFormatEcr.format(this.dateAu));
}
 
protected void createListeValues() {
 
final SQLRowValues vals = new SQLRowValues(tableEcriture);
 
vals.put("ID_JOURNAL", null);
vals.put("ID_COMPTE_PCE", null);
vals.put("COMPTE_NUMERO", null);
vals.put("COMPTE_NOM", null);
vals.put("JOURNAL_CODE", null);
vals.put("JOURNAL_NOM", null);
vals.putRowValues("ID_MOUVEMENT").put("NUMERO", null);
vals.put("CREDIT", null);
vals.put("DEBIT", null);
vals.put("DATE", null);
vals.put("NOM", null);
 
final SQLRowValuesListFetcher fetcher = new SQLRowValuesListFetcher(vals);
fetcher.setSelTransf(new ITransformer<SQLSelect, SQLSelect>() {
@Override
public SQLSelect transformChecked(SQLSelect sel) {
 
Where w = (new Where(tableEcriture.getField("DATE"), JournauxSheetXML.this.dateDu, JournauxSheetXML.this.dateAu));
 
Where w2 = new Where(tableEcriture.getField("ID_JOURNAL"), "=", JournauxSheetXML.this.id);
 
if (JournauxSheetXML.this.lettrage == MODELETTREE) {
Object o = null;
w = w.and(new Where(tableEcriture.getField("LETTRAGE"), "<>", o));
w = w.and(new Where(tableEcriture.getField("LETTRAGE"), "!=", ""));
} else {
if (JournauxSheetXML.this.lettrage == MODENONLETTREE) {
Object o = null;
Where w3 = new Where(tableEcriture.getField("LETTRAGE"), "=", o);
w = w.and(w3.or(new Where(tableEcriture.getField("LETTRAGE"), "=", "")));
}
}
 
if (JournauxSheetXML.this.compteDeb.equals(JournauxSheetXML.this.compteEnd)) {
w = w.and(new Where(tableEcriture.getField("COMPTE_NUMERO"), "=", JournauxSheetXML.this.compteDeb));
} else {
w = w.and(new Where(tableEcriture.getField("COMPTE_NUMERO"), (Object) JournauxSheetXML.this.compteDeb, (Object) JournauxSheetXML.this.compteEnd));
}
 
if (!UserManager.getInstance().getCurrentUser().getRights().haveRight(ComptaUserRight.ACCES_NOT_RESCTRICTED_TO_411)) {
// TODO Show Restricted acces in UI
w = w.and(new Where(tableEcriture.getField("COMPTE_NUMERO"), "LIKE", "411%"));
}
 
sel.setWhere(w.and(w2));
sel.addFieldOrder(sel.getAlias(tableEcriture.getField("ID_JOURNAL")));
sel.addFieldOrder(sel.getAlias(tableEcriture.getField("DATE")));
sel.addFieldOrder(sel.getAlias(tableMvt.getField("NUMERO")));
 
return sel;
}
});
 
List<SQLRowValues> list = fetcher.fetch();
 
System.err.println("START CREATE JOURNAUX, NB ecritures " + list.size());
 
long totalDebit, totalCredit;
 
totalDebit = 0;
totalCredit = 0;
int prevIdMvt = 0;
 
String firstJournal = tableJournal.getRow(this.id).getString("NOM");
 
List<Map<String, Object>> tableauVals = new ArrayList<Map<String, Object>>();
this.listAllSheetValues.put(0, tableauVals);
 
Map<Integer, String> style = new HashMap<Integer, String>();
this.styleAllSheetValues.put(0, style);
 
for (int i = 0; i < list.size(); i++) {
 
Map<String, Object> values = new HashMap<String, Object>();
 
SQLRowValues rowEcr = list.get(i);
 
SQLRowAccessor rowMvt = rowEcr.getForeign("ID_MOUVEMENT");
 
// si on change de mouvement alors on applique le style Titre 1
if (prevIdMvt != rowMvt.getID()) {
prevIdMvt = rowMvt.getID();
style.put(tableauVals.size(), "Titre 1");
} else {
style.put(tableauVals.size(), "Normal");
}
values.put("DATE", dateFormatEcr.format(rowEcr.getDate("DATE").getTime()));
 
values.put("NUMERO_COMPTE", rowEcr.getString("COMPTE_NUMERO"));
 
values.put("NUMERO_MOUVEMENT", rowMvt.getObject("NUMERO"));
Object libelle = rowEcr.getObject("NOM");
values.put("LIBELLE", libelle);
long deb = ((Long) rowEcr.getObject("DEBIT")).longValue();
long cred = ((Long) rowEcr.getObject("CREDIT")).longValue();
 
long solde = deb - cred;
 
totalCredit += cred;
totalDebit += deb;
 
values.put("DEBIT", (deb == 0) ? new Double(0) : new Double(GestionDevise.currencyToString(deb, false)));
values.put("CREDIT", (cred == 0) ? new Double(0) : new Double(GestionDevise.currencyToString(cred, false)));
values.put("SOLDE", (solde == 0) ? new Double(0) : new Double(GestionDevise.currencyToString(solde, false)));
 
tableauVals.add(values);
 
}
 
Map<String, Object> sheetVals = new HashMap<String, Object>();
this.mapAllSheetValues.put(0, sheetVals);
 
makeEntete(sheetVals, firstJournal);
 
sheetVals.put("TOTAL_DEBIT", (totalDebit == 0) ? new Double(0) : new Double(GestionDevise.currencyToString(totalDebit, false)));
sheetVals.put("TOTAL_CREDIT", (totalCredit == 0) ? new Double(0) : new Double(GestionDevise.currencyToString(totalCredit, false)));
sheetVals.put("TOTAL_SOLDE", (totalDebit - totalCredit == 0) ? new Double(0) : new Double(GestionDevise.currencyToString(totalDebit - totalCredit, false)));
 
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/report/GrandLivreSheet.java
194,9 → 194,9
}
 
sel.setWhere(w);
sel.addRawOrder("\"ECRITURE\".\"COMPTE_NUMERO\"");
sel.addRawOrder("\"ECRITURE\".\"DATE\"");
sel.addRawOrder("\"MOUVEMENT\".\"NUMERO\"");
sel.addFieldOrder(tableEcriture.getField("COMPTE_NUMERO"));
sel.addFieldOrder(tableEcriture.getField("DATE"));
sel.addFieldOrder(tableMvt.getField("NUMERO"));
System.err.println(sel.asString());
return sel;
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/report/Map2033B.java
371,7 → 371,7
* PRODUITS EXCEPTIONNELS
******************************************************************************************/
// 290 -SommeSolde( 77, 77* )-SommeSolde( 787, 789* )-SommeSolde( 797, 799* )
long v290 = -this.sommeCompte.soldeCompte(771, 771, true, this.dateDeb, this.dateFin) - this.sommeCompte.soldeCompte(775, 778, true, this.dateDeb, this.dateFin)
long v290 = -this.sommeCompte.soldeCompte(771, 772, true, this.dateDeb, this.dateFin) - this.sommeCompte.soldeCompte(775, 778, true, this.dateDeb, this.dateFin)
- this.sommeCompte.soldeCompte(787, 787, true, this.dateDeb, this.dateFin) - this.sommeCompte.soldeCompte(797, 797, true, this.dateDeb, this.dateFin);
this.m.put("PCHARGES3.22", GestionDevise.currencyToString(v290, false));
 
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/action/ListeDesEcrituresAction.java
14,6 → 14,9
package org.openconcerto.erp.core.finance.accounting.action;
 
import org.openconcerto.erp.action.CreateFrameAbstractAction;
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.common.ui.IListFilterDatePanel;
import org.openconcerto.erp.core.common.ui.IListTotalPanel;
import org.openconcerto.erp.core.common.ui.PanelFrame;
import org.openconcerto.erp.core.finance.accounting.element.EcritureSQLElement;
import org.openconcerto.erp.core.finance.accounting.element.MouvementSQLElement;
21,7 → 24,12
import org.openconcerto.erp.rights.ComptaUserRight;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowListRSH;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.users.UserManager;
import org.openconcerto.sql.view.IListFrame;
28,16 → 36,17
import org.openconcerto.sql.view.ListeAddPanel;
import org.openconcerto.sql.view.list.IListe;
import org.openconcerto.sql.view.list.SQLTableModelSourceOnline;
import org.openconcerto.utils.Tuple2;
import org.openconcerto.ui.DefaultGridBagConstraints;
 
import java.awt.GridBagConstraints;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
 
import javax.swing.AbstractAction;
import javax.swing.Action;
69,13 → 78,13
 
final IListFrame frame = new IListFrame(new ListeAddPanel(element, new IListe(src)) {
 
@Override
protected GridBagConstraints createConstraints() {
final GridBagConstraints res = super.createConstraints();
res.gridwidth = GridBagConstraints.REMAINDER;
res.gridy = 1;
return res;
}
// @Override
// protected GridBagConstraints createConstraints() {
// final GridBagConstraints res = super.createConstraints();
// res.gridwidth = GridBagConstraints.REMAINDER;
// res.gridy = 1;
// return res;
// }
 
@Override
protected void handleAction(JButton source, ActionEvent evt) {
97,35 → 106,27
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getPanel().setSearchFullMode(true);
 
GridBagConstraints c = new GridBagConstraints();
c.gridy = 0;
GridBagConstraints c = new DefaultGridBagConstraints();
c.gridy = 4;
c.gridx = 0;
c.gridwidth = 1;
c.weightx = 1;
 
Map<String, Tuple2<Date, Date>> m = new HashMap<String, Tuple2<Date, Date>>();
Calendar cal = Calendar.getInstance();
cal.set(Calendar.DAY_OF_MONTH, 1);
Date d = cal.getTime();
// TODO mettre dans la map du filtre les dates des exercices
SQLRow rowExercice = Configuration.getInstance().getBase().getTable("EXERCICE_COMMON").getRow(ComptaPropsConfiguration.getInstanceCompta().getRowSociete().getInt("ID_EXERCICE_COMMON"));
 
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
Date d2 = cal.getTime();
m.put("Mois courant", new Tuple2<Date, Date>(d, cal.getTime()));
final IListFilterDatePanel comp = new IListFilterDatePanel(frame.getPanel().getListe(), element.getTable().getField("DATE"), IListFilterDatePanel.getDefaultMap());
comp.setDateDu((Date) rowExercice.getObject("DATE_DEB"));
c.weightx = 1;
frame.getPanel().add(comp, c);
 
cal.set(Calendar.DAY_OF_MONTH, 1);
cal.add(Calendar.MONTH, -6);
m.put("Les 6 derniers mois", new Tuple2<Date, Date>(cal.getTime(), d2));
 
// final IListFilterDatePanel comp = new IListFilterDatePanel(frame.getPanel().getListe(),
// element.getTable().getField("DATE"), m);
//
// List<SQLField> l = new ArrayList<SQLField>();
// l.add(element.getTable().getField("DEBIT"));
// l.add(element.getTable().getField("CREDIT"));
 
//
// IListTotalPanel comp2 = new IListTotalPanel(frame.getPanel().getListe(), l);
// frame.getPanel().add(comp, c);
// c.gridx++;
// c.weightx = 0;
// frame.getPanel().add(comp2, c);
 
// Renderer
138,7 → 139,7
frame.getPanel().getListe().setSQLEditable(false);
 
table.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
public void mouseReleased(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON3) {
JPopupMenu menuDroit = new JPopupMenu();
menuDroit.add(new AbstractAction("Contrepassation") {
155,6 → 156,15
}
});
 
if (e.getModifiersEx() == 128) {
menuDroit.add(new AbstractAction("Mettre à jour les noms de piéces") {
public void actionPerformed(ActionEvent event) {
 
correctNomPiece();
}
});
}
 
menuDroit.show(e.getComponent(), e.getPoint().x, e.getPoint().y);
}
}
172,4 → 182,43
 
return frame;
}
 
public void correctNomPiece() {
SQLTable tableMvt = Configuration.getInstance().getRoot().findTable("MOUVEMENT");
SQLTable tablePiece = Configuration.getInstance().getRoot().findTable("PIECE");
SQLSelect sel = new SQLSelect(tableMvt.getBase());
sel.addSelect(tableMvt.getKey());
sel.addSelect(tableMvt.getField("SOURCE"));
sel.addSelect(tableMvt.getField("IDSOURCE"));
sel.addSelect(tableMvt.getField("ID_MOUVEMENT_PERE"));
sel.addSelect(tableMvt.getField("ID_PIECE"));
sel.addJoin("LEFT", tableMvt.getField("ID_PIECE"));
sel.addSelect(sel.getAlias(tablePiece.getField("NOM")));
 
Where w = new Where(tableMvt.getField("ID_MOUVEMENT_PERE"), "=", tableMvt.getUndefinedID());
w = w.and(new Where(tableMvt.getField("SOURCE"), "=", "SAISIE_VENTE_FACTURE"));
w = w.and(new Where(sel.getAlias(tablePiece.getField("NOM")), "LIKE", "%Saisie vente facture%"));
sel.setWhere(w);
 
System.err.println(sel.asString());
 
List<SQLRow> rows = (List<SQLRow>) Configuration.getInstance().getBase().getDataSource().execute(sel.asString(), SQLRowListRSH.createFromSelect(sel, tableMvt));
 
for (SQLRow sqlRow : rows) {
SQLRow rowPiece = sqlRow.getForeignRow("ID_PIECE");
String nom = rowPiece.getString("NOM");
if (nom.startsWith("Saisie vente facture")) {
SQLRowValues rowVals = rowPiece.asRowValues();
String nomNew = nom.replaceAll("Saisie vente facture", "Fact. vente");
rowVals.put("NOM", nomNew);
try {
rowVals.update();
} catch (SQLException exn) {
// TODO Bloc catch auto-généré
exn.printStackTrace();
}
}
}
 
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/GenerationPointagePanel.java
58,7 → 58,7
this.add(new JLabel("Mois"), c);
c.gridx++;
 
ComboSQLRequest comboReq = new ComboSQLRequest(moisElt.getComboRequest());
ComboSQLRequest comboReq = moisElt.getComboRequest(true);
this.combo.uiInit(comboReq);
this.add(this.combo, c);
 
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/ImpressionJournauxPanel.java
14,10 → 14,12
package org.openconcerto.erp.core.finance.accounting.ui;
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.config.Gestion;
import org.openconcerto.erp.core.finance.accounting.model.SelectJournauxModel;
import org.openconcerto.erp.core.finance.accounting.report.GrandLivreSheet;
import org.openconcerto.erp.core.finance.accounting.report.JournauxMoisSheet;
import org.openconcerto.erp.core.finance.accounting.report.JournauxSheet;
import org.openconcerto.erp.core.finance.accounting.report.JournauxSheetXML;
import org.openconcerto.erp.generationDoc.SpreadSheetGeneratorCompta;
import org.openconcerto.erp.generationDoc.SpreadSheetGeneratorListener;
import org.openconcerto.erp.preferences.DefaultNXProps;
26,6 → 28,7
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.JDate;
import org.openconcerto.ui.TitledSeparator;
import org.openconcerto.utils.ExceptionHandler;
import org.openconcerto.utils.text.SimpleDocumentListener;
 
import java.awt.Dimension;
55,6 → 58,7
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
 
62,11 → 66,8
 
private final JDate dateDeb, dateEnd;
private JTable tableJrnl;
// private boolean isValidated;
private JButton valid;
private JButton annul;
private JCheckBox checkImpr;
private JCheckBox checkVisu;
private JCheckBox checkCentralMois;
private JTextField compteDeb, compteEnd;
private int mode = GrandLivreSheet.MODEALL;
84,7 → 85,7
this.dateEnd = new JDate();
this.tableJrnl = new JTable(new SelectJournauxModel());
 
this.add(new JLabel("Période du"), c);
this.add(new JLabel("Période du", SwingConstants.RIGHT), c);
c.gridx++;
c.weightx = 1;
this.add(this.dateDeb, c);
118,7 → 119,7
this.compteEnd = new JTextField();
c.gridy++;
c.gridx = 0;
this.add(new JLabel("Du compte "), c);
this.add(new JLabel("Du compte ", SwingConstants.RIGHT), c);
c.gridx++;
c.weightx = 1;
this.add(this.compteDeb, c);
156,8 → 157,6
 
this.valid = new JButton("Valider");
this.annul = new JButton("Fermer");
this.checkImpr = new JCheckBox("Impression");
this.checkVisu = new JCheckBox("Visualisation");
 
// Radio mode
JRadioButton radioAll = new JRadioButton(new AbstractAction("Toutes") {
215,22 → 214,16
this.bar.setStringPainted(true);
this.add(this.bar, c);
 
c.gridwidth = 2;
c.gridy++;
c.weightx = 0;
c.weighty = 0;
this.add(this.checkImpr, c);
this.checkImpr.setSelected(true);
c.gridx += 2;
this.add(this.checkVisu, c);
c.gridx = 3;
c.fill = GridBagConstraints.NONE;
c.anchor = GridBagConstraints.EAST;
c.gridwidth = 1;
final JPanel actionPanel = new JPanel();
actionPanel.add(this.valid);
actionPanel.add(this.annul);
 
c.gridy++;
c.gridx = 0;
c.fill = GridBagConstraints.NONE;
c.anchor = GridBagConstraints.CENTER;
this.add(this.valid, c);
c.gridx += 2;
this.add(this.annul, c);
this.add(actionPanel, c);
checkValidity();
 
this.valid.addActionListener(new ActionListener() {
241,22 → 234,44
new Thread(new Runnable() {
public void run() {
int[] idS = ((SelectJournauxModel) tableJrnl.getModel()).getSelectedIds(tableJrnl.getSelectedRows());
if (checkCentralMois.isSelected()) {
JournauxSheet bSheet;
if (checkCentralMois.isSelected()) {
bSheet = new JournauxMoisSheet(idS, dateDeb.getDate(), dateEnd.getDate(), mode);
final SpreadSheetGeneratorCompta generator = new SpreadSheetGeneratorCompta(bSheet, "Journal_" + Calendar.getInstance().getTimeInMillis(), false, true);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
bar.setValue(2);
generator.addGenerateListener(ImpressionJournauxPanel.this);
}
});
} else {
bSheet = new JournauxSheet(idS, dateDeb.getDate(), dateEnd.getDate(), mode, compteDeb.getText().trim(), compteEnd.getText().trim());
for (int i = 0; i < idS.length; i++) {
final JournauxSheetXML xmlSheet = new JournauxSheetXML(idS[i], dateDeb.getDate(), dateEnd.getDate(), mode, compteDeb.getText().trim(), compteEnd.getText().trim());
SwingUtilities.invokeLater(new Runnable() {
public void run() {
bar.setValue(2);
}
});
try {
xmlSheet.createDocument();
xmlSheet.getOrCreatePDFDocumentFile(false, true);
Gestion.openPDF(xmlSheet.getGeneratedPDFFile());
} catch (Exception exn) {
ExceptionHandler.handle("Erreur lors de la création du journal !", exn);
}
 
final SpreadSheetGeneratorCompta generator = new SpreadSheetGeneratorCompta(bSheet, "Journal_" + Calendar.getInstance().getTimeInMillis(), checkImpr.isSelected(), checkVisu
.isSelected());
}
SwingUtilities.invokeLater(new Runnable() {
public void run() {
bar.setValue(2);
generator.addGenerateListener(ImpressionJournauxPanel.this);
bar.setValue(3);
bar.setString("Terminée");
valid.setEnabled(true);
}
});
 
}
 
}
}).start();
}
});
315,7 → 330,6
Date beginDate = this.dateDeb.getDate();
Date endDate = this.dateEnd.getDate();
 
// System.err.println("Check validity between ");
if (beginDate == null || endDate == null) {
this.valid.setEnabled(false);
} else {
336,7 → 350,7
if (this.compteDeb.getText().trim().compareToIgnoreCase(this.compteEnd.getText().trim()) > 0) {
this.valid.setEnabled(false);
} else {
if (beginDate.after(endDate)) {
if (beginDate == null || beginDate.after(endDate)) {
this.valid.setEnabled(false);
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/EtatJournauxPanel.java
27,6 → 27,7
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.users.UserManager;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.utils.GestionDevise;
 
import java.awt.Dimension;
75,12 → 76,9
 
this.setLayout(new GridBagLayout());
 
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(2, 2, 1, 2);
final GridBagConstraints c = new DefaultGridBagConstraints();
c.fill = GridBagConstraints.BOTH;
c.anchor = GridBagConstraints.NORTHWEST;
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 2;
c.gridheight = 1;
c.weightx = 1;
114,20 → 112,6
 
// On recupere les differents journaux
SQLTable journalTable = base.getTable("JOURNAL");
// SQLSelect selJournal = new SQLSelect(base);
//
// selJournal.addSelect(journalTable.getField("ID"));
// selJournal.addSelect(journalTable.getField("NOM"));
// selJournal.addSelect(journalTable.getField("CODE"));
//
// selJournal.addRawOrder("\"JOURNAL\".\"NOM\"");
//
// String reqJournal = selJournal.asString();
// Object obJournal = base.getDataSource().execute(reqJournal, new ArrayListHandler());
//
// List myListJournal = (List) obJournal;
//
// if (myListJournal.size() != 0) {
 
List<SQLRow> liste = SQLBackgroundTableCache.getInstance().getCacheForTable(journalTable).getRows();
for (int k = 0; k < liste.size(); k++) {
191,24 → 175,6
c.weightx = 1;
c.weighty = 0;
 
// Récupération des ecritures du journal avec le total par mois
// SQLTable ecritureTable = base.getTable("ECRITURE");
// SQLSelect sel = new SQLSelect(base);
//
// sel.addSelect(ecritureTable.getField("DATE"), "YEAR");
// sel.addSelect(ecritureTable.getField("DATE"), "MONTH");
// sel.addSelect(ecritureTable.getField("DEBIT"), "SUM");
// sel.addSelect(ecritureTable.getField("CREDIT"), "SUM");
//
// Where w = new Where(ecritureTable.getField("ID_JOURNAL"), "=", jrnl.getId());
//
// sel.setWhere(w);
//
// sel.setDistinct(true);
//
// String req = sel.asString() + " GROUP BY YEAR(ECRITURE.DATE), MONTH(ECRITURE.DATE) ORDER
// BY ECRITURE.DATE";
 
String req = "SELECT DISTINCT EXTRACT(YEAR FROM \"" + baseName + "\".\"ECRITURE\".\"DATE\"), " + "EXTRACT(MONTH FROM \"" + baseName + "\".\"ECRITURE\".\"DATE\")," + " SUM(\"" + baseName
+ "\".\"ECRITURE\".\"DEBIT\"), " + "SUM(\"" + baseName + "\".\"ECRITURE\".\"CREDIT\")" + " FROM \"" + baseName + "\".\"ECRITURE\" " + "WHERE (\"" + baseName
+ "\".\"ECRITURE\".\"ID\" != 1) " + "AND ((\"" + baseName + "\".\"ECRITURE\".\"ARCHIVE\" = 0) " + "AND (\"" + baseName + "\".\"ECRITURE\".\"ID_JOURNAL\" = " + jrnl.getId() + ")) "
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/EtatChargePanel.java
22,7 → 22,6
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.sqlobject.ElementComboBox;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.state.JTableStateManager;
64,9 → 63,6
private JTextField textAnnee;
private EtatChargeModel[] model;
private static final NumberFormat numberFormat = new DecimalFormat("0.00");
// private final static SQLBase base = ((ComptaPropsConfiguration)
// Configuration.getInstance()).getSQLBaseSociete();
private final static SQLTable tableCaisse = Configuration.getInstance().getBase().getTable("CAISSE_COTISATION");
 
public EtatChargePanel() {
this.setLayout(new GridBagLayout());
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/SaisieKmItemTable.java
32,7 → 32,10
import org.openconcerto.sql.view.list.RowValuesTableControlPanel;
import org.openconcerto.sql.view.list.RowValuesTableModel;
import org.openconcerto.sql.view.list.SQLTableElement;
import org.openconcerto.sql.view.list.TextTableCellEditorWithCompletion;
import org.openconcerto.sql.view.list.ValidStateChecker;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.utils.checks.ValidState;
 
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
109,7 → 112,18
 
// Autocompletion
final AutoCompletionManager m = new AutoCompletionManager(this.tableElementNumeroCompte, ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete().getField(
"COMPTE_PCE.NUMERO"), this.table, this.table.getRowValuesTableModel(), ITextWithCompletion.MODE_STARTWITH, true);
"COMPTE_PCE.NUMERO"), this.table, this.table.getRowValuesTableModel(), ITextWithCompletion.MODE_STARTWITH, true, false, new ValidStateChecker() {
 
ComptePCESQLElement elt = Configuration.getInstance().getDirectory().getElement(ComptePCESQLElement.class);
 
@Override
public ValidState getValidState(Object o) {
if (o != null) {
return elt.getCompteNumeroValidState(o.toString());
}
return super.getValidState(o);
}
});
m.fill("NOM", "NOM");
m.setFillWithField("NUMERO");
 
119,6 → 133,8
m2.fill("NUMERO", "NUMERO");
m2.setFillWithField("NOM");
 
TextTableCellEditorWithCompletion t = (TextTableCellEditorWithCompletion) this.tableElementNumeroCompte.getTableCellEditor(this.table);
 
this.add(new RowValuesTableControlPanel(this.table), c);
 
c.gridy++;
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/ui/SuppressionEcrituresPanel.java
111,7 → 111,7
 
SQLSelect sel = new SQLSelect(b);
sel.addSelect(tableMvt.getField("NUMERO"));
sel.setWhere("MOUVEMENT.ID_PIECE", "=", idPiece);
sel.setWhere(tableMvt.getField("ID_PIECE"), "=", idPiece);
 
List l = (List) b.getDataSource().execute(sel.asString(), new ArrayListHandler());
 
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/model/AssociationAnalytiqueModel.java
202,7 → 202,7
selAssoc.addSelect(associationTable.getField("ID_COMPTE_PCE"));
selAssoc.addSelect(associationTable.getField("ID_REPARTITION_ANALYTIQUE"));
 
selAssoc.setWhere("ASSOCIATION_COMPTE_ANALYTIQUE.ID_AXE_ANALYTIQUE", "=", ((Axe) this.axes.get(j)).getId());
selAssoc.setWhere(associationTable.getField("ID_AXE_ANALYTIQUE"), "=", ((Axe) this.axes.get(j)).getId());
 
String reqAssoc = selAssoc.asString();
Object obAssoc = base.getDataSource().execute(reqAssoc, new ArrayListHandler());
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/model/SelectJournauxModel.java
17,37 → 17,24
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLBase;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowListRSH;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
 
import java.util.List;
import java.util.Vector;
 
import javax.swing.table.AbstractTableModel;
 
import org.apache.commons.dbutils.handlers.ArrayListHandler;
 
 
public class SelectJournauxModel extends AbstractTableModel {
 
private static final SQLBase base = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete();
private static final SQLTable tableJournal = base.getTable("JOURNAL");
private Vector journaux;
private List<SQLRow> journaux;
private String[] titres;
 
public SelectJournauxModel() {
this.journaux = SQLRowListRSH.execute(new SQLSelect(base).addSelectStar(tableJournal));
 
this.journaux = new Vector();
SQLSelect selJrnl = new SQLSelect(base);
selJrnl.addSelect("JOURNAL.ID");
String req = selJrnl.asString();
List l = (List) base.getDataSource().execute(req, new ArrayListHandler());
 
for (int i = 0; i < l.size(); i++) {
Object[] tmp = (Object[]) l.get(i);
this.journaux.add(tableJournal.getRow(Integer.parseInt(tmp[0].toString())));
}
 
this.titres = new String[2];
this.titres[0] = "Code";
this.titres[1] = "Libellé";
70,10 → 57,10
 
public Object getValueAt(int rowIndex, int columnIndex) {
if (columnIndex == 0) {
return ((SQLRow) this.journaux.get(rowIndex)).getObject("CODE");
return this.journaux.get(rowIndex).getObject("CODE");
} else {
if (columnIndex == 1) {
return ((SQLRow) this.journaux.get(rowIndex)).getObject("NOM");
return this.journaux.get(rowIndex).getObject("NOM");
} else {
return null;
}
91,7 → 78,7
}
 
public int getIdForRow(int row) {
return ((SQLRow) this.journaux.get(row)).getID();
return this.journaux.get(row).getID();
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/accounting/model/AnalytiqueModel.java
68,7 → 68,7
SQLSelect sel = new SQLSelect(base);
sel.addSelect(posteTable.getField("ID"));
sel.addSelect(posteTable.getField("NOM"));
sel.setWhere("POSTE_ANALYTIQUE.ID_AXE_ANALYTIQUE", "=", IDAxe);
sel.setWhere(posteTable.getField("ID_AXE_ANALYTIQUE"), "=", IDAxe);
 
String req = sel.asString();
 
105,14 → 105,15
 
// SELECT Rep.NOM, ID_POSTE, taux FROM REP, REP_ELEME
// WHERE REP_ELEME.ID_POSTE = id, REP_ELEM.IDREP = REp.ID)
final SQLTable repartAnalytiqueT = base.getTable("REPARTITION_ANALYTIQUE");
SQLSelect sel2 = new SQLSelect(base);
sel2.addSelect("REPARTITION_ANALYTIQUE.NOM");
sel2.addSelect("REPARTITION_ANALYTIQUE_ELEMENT.TAUX");
sel2.addSelect("REPARTITION_ANALYTIQUE_ELEMENT.ID_POSTE_ANALYTIQUE");
sel2.addSelect("REPARTITION_ANALYTIQUE_ELEMENT.ID_REPARTITION_ANALYTIQUE");
sel2.addSelect("REPARTITION_ANALYTIQUE_ELEMENT.ID");
sel2.addSelect(repartAnalytiqueT.getField("NOM"));
sel2.addSelect(repartAnalytiqueT.getField("TAUX"));
sel2.addSelect(repartAnalytiqueT.getField("ID_POSTE_ANALYTIQUE"));
sel2.addSelect(repartAnalytiqueT.getField("ID_REPARTITION_ANALYTIQUE"));
sel2.addSelect(repartAnalytiqueT.getKey());
 
Where w = new Where(base.getTable("REPARTITION_ANALYTIQUE_ELEMENT").getField("ID_REPARTITION_ANALYTIQUE"), "=", base.getTable("REPARTITION_ANALYTIQUE").getField("ID"));
Where w = new Where(base.getTable("REPARTITION_ANALYTIQUE_ELEMENT").getField("ID_REPARTITION_ANALYTIQUE"), "=", repartAnalytiqueT.getKey());
Where w2 = new Where(posteTable.getField("ID_AXE_ANALYTIQUE"), "=", this.idAxe);
Where w3 = new Where(posteTable.getField("ID"), "=", base.getTable("REPARTITION_ANALYTIQUE_ELEMENT").getField("ID_POSTE_ANALYTIQUE"));
 
347,7 → 348,7
SQLSelect selAssoc = new SQLSelect(base);
selAssoc.addSelect(assocTable.getField("ID"));
selAssoc.addSelect(assocTable.getField("ID_COMPTE_PCE"));
selAssoc.setWhere("ASSOCIATION_COMPTE_ANALYTIQUE.ID_REPARTITION_ANALYTIQUE", "=", rep.getId());
selAssoc.setWhere(assocTable.getField("ID_REPARTITION_ANALYTIQUE"), "=", rep.getId());
 
String reqAssoc = selAssoc.asString();
Object obAssoc = base.getDataSource().execute(reqAssoc, new ArrayListHandler());
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/tax/model/TaxeCache.java
31,18 → 31,24
import org.apache.commons.dbutils.handlers.ArrayListHandler;
 
public final class TaxeCache {
private transient final Map<Integer, Float> mapTaux = new HashMap<Integer, Float>();
private static TaxeCache instance;
private transient Integer firstIdTaxe = null;
 
private TaxeCache() {
static private final SQLSelect getSel() {
final DBRoot root = ((ComptaPropsConfiguration) Configuration.getInstance()).getRootSociete();
final SQLTable table = root.getTable("TAXE");
final SQLSelect sel = new SQLSelect(table.getBase());
sel.addSelect(table.getField("ID_TAXE"));
sel.addSelect(table.getField("TAUX"));
return sel;
}
 
private transient final Map<Integer, Float> mapTaux = new HashMap<Integer, Float>();
private static TaxeCache instance;
private transient Integer firstIdTaxe = null;
 
private TaxeCache() {
final SQLSelect sel = getSel();
final String req = sel.asString();
root.getDBSystemRoot().getDataSource().execute(req, new ResultSetHandler() {
sel.getSelectFields().get(0).getDBSystemRoot().getDataSource().execute(req, new ResultSetHandler() {
 
public Object handle(final ResultSet resultSet) throws SQLException {
while (resultSet.next()) {
70,9 → 76,7
public Integer getFirstTaxe() {
if (this.firstIdTaxe == null) {
final SQLBase table = ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete();
final SQLSelect sel = new SQLSelect(table);
sel.addSelect("TAXE.ID_TAXE");
sel.addSelect("TAXE.TAUX");
final SQLSelect sel = getSel();
final String req = sel.asString();
final List<Object[]> list = (List<Object[]>) table.getDataSource().execute(req, new ArrayListHandler());
if (list != null && !list.isEmpty()) {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/finance/payment/ui/ListeDesChequesAEncaisserPanel.java
353,7 → 353,7
}
});
 
if (UserManager.getInstance().getCurrentUser().getRights().haveRight(ComptaTotalUserRight.TOTAL)) {
if (UserManager.getInstance().getCurrentUser().getRights().haveRight(ComptaTotalUserRight.MENU)) {
 
menuDroit.add(new AbstractAction("Régularisation en comptabilité") {
 
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/payroll/report/FichePayeSheet.java
300,7 → 300,7
// Element Devis
SQLSelect selElt = new SQLSelect(base);
selElt.addSelect(tableFicheElt.getField("ID"));
selElt.setWhere("FICHE_PAYE_ELEMENT.ID_FICHE_PAYE", "=", this.row.getID());
selElt.setWhere(tableFicheElt.getField("ID_FICHE_PAYE"), "=", this.row.getID());
 
String req = selElt.asString() + " ORDER BY \"FICHE_PAYE_ELEMENT\".\"POSITION\"";
List l = (List) base.getDataSource().execute(req, new ArrayListHandler());
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/payroll/ui/HistoriqueFichePayePanel.java
99,11 → 99,9
SQLElement eltFiche = Configuration.getInstance().getDirectory().getElement("FICHE_PAYE");
 
// Liste à selectionner
List<String> l = new ArrayList<String>();
l.add("NOM");
l.add("PRENOM");
this.jListPanel = new JListSQLTablePanel(e.getTable(), l, "Tous");
 
this.jListPanel = new JListSQLTablePanel(JListSQLTablePanel.createComboRequest(e.getTable(), true), "Tous");
 
// IListe
final SQLTableModelSourceOnline src = eltFiche.getTableSource(true);
src.getReq().setWhere(Where.FALSE);
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/payroll/element/FichePayeSQLElement.java
787,7 → 787,7
SQLSelect selAllElt = new SQLSelect(tableFiche.getBase());
selAllElt.addSelect(tableFicheElt.getField("ID"));
selAllElt.addSelect(tableFicheElt.getField("POSITION"));
selAllElt.setWhere("FICHE_PAYE_ELEMENT.ID_FICHE_PAYE", "=", oldID);
selAllElt.setWhere(tableFicheElt.getField("ID_FICHE_PAYE"), "=", oldID);
// selAllElt.setArchivedPolicy(SQLSelect.BOTH);
selAllElt.setDistinct(true);
selAllElt.addRawOrder("\"FICHE_PAYE_ELEMENT\".\"POSITION\"");
/trunk/OpenConcerto/src/org/openconcerto/erp/core/humanresources/payroll/element/VariablePayeSQLElement.java
624,7 → 624,7
SQLSelect sel = new SQLSelect(getTable().getBase());
sel.addSelect(getTable().getField("ID"));
System.err.println("Check variable");
sel.setWhere("VARIABLE_PAYE.FORMULE", "LIKE", "%" + row.getString("NOM") + "%");
sel.setWhere(new Where(getTable().getField("FORMULE"), "LIKE", "%" + row.getString("NOM") + "%"));
sel.andWhere(new Where(getTable().getField("ID"), "!=", id));
 
String req = sel.asString();
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/shipment/ui/BonDeLivraisonItemTable.java
37,6 → 37,7
import org.openconcerto.sql.view.list.RowValuesTable;
import org.openconcerto.sql.view.list.RowValuesTableModel;
import org.openconcerto.sql.view.list.SQLTableElement;
import org.openconcerto.sql.view.list.ValidStateChecker;
import org.openconcerto.ui.table.XTableColumnModel;
 
import java.math.BigDecimal;
317,7 → 318,7
m2.setWhere(new Where(sqlTableArticle.getField("OBSOLETE"), "=", Boolean.FALSE));
 
final AutoCompletionManager m3 = new AutoCompletionManager(tableElementArticle, sqlTableArticle.getField("NOM"), this.table, this.table.getRowValuesTableModel(),
ITextWithCompletion.MODE_CONTAINS, true, true);
ITextWithCompletion.MODE_CONTAINS, true, true, new ValidStateChecker());
m3.fill("CODE", "CODE");
m3.fill("NOM", "NOM");
for (String string : completionField) {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/shipment/component/BonDeLivraisonSQLComponent.java
688,7 → 688,7
BonDeLivraisonItemSQLElement bonElt = new BonDeLivraisonItemSQLElement();
selBonItem.addSelect(bonElt.getTable().getField("ID_SAISIE_VENTE_FACTURE_ELEMENT"));
selBonItem.addSelect(bonElt.getTable().getField("QTE_LIVREE"));
selBonItem.setWhere("BON_DE_LIVRAISON_ELEMENT.ID_BON_DE_LIVRAISON", "=", idBon);
selBonItem.setWhere(bonElt.getTable().getField("ID_BON_DE_LIVRAISON"), "=", idBon);
 
String reqBonItem = selBonItem.asString();
Object obBonItem = getTable().getBase().getDataSource().execute(reqBonItem, new ArrayListHandler());
721,7 → 721,7
BonDeLivraisonItemSQLElement bonElt = new BonDeLivraisonItemSQLElement();
selBonItem.addSelect(bonElt.getTable().getField("ID_SAISIE_VENTE_FACTURE_ELEMENT"));
selBonItem.addSelect(bonElt.getTable().getField("QTE_LIVREE"));
selBonItem.setWhere("BON_DE_LIVRAISON_ELEMENT.ID_BON_DE_LIVRAISON", "=", idBon);
selBonItem.setWhere(bonElt.getTable().getField("ID_BON_DE_LIVRAISON"), "=", idBon);
 
String reqBonItem = selBonItem.asString();
Object obBonItem = getTable().getBase().getDataSource().execute(reqBonItem, new ArrayListHandler());
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/action/ListeSaisieVenteFactureAction.java
65,6 → 65,7
import java.awt.event.ActionListener;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
 
import javax.swing.AbstractAction;
228,8 → 229,8
};
// this.frame.getPanel().getListe().addRowActions(mouseListener.getRowActions());
this.frame.getPanel().getListe().addIListeActions(mouseListener.getRowActions());
this.frame.getPanel().getListe().setDefaultRowAction(mouseListener.getDefaultRowAction());
 
 
return this.frame;
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/ui/InvoiceEditGroup.java
29,11 → 29,11
 
final Group gCustomer = new Group("sales.invoice.customer");
gCustomer.add("ID_CLIENT", LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
add(gCustomer, LayoutHints.DEFAULT_LARGE_GROUP_HINTS);
add(gCustomer, LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
 
final Group gAddress = new Group("sales.invoice.address");
gAddress.add("ID_ADRESSE");
add(gAddress, LayoutHints.DEFAULT_LARGE_GROUP_HINTS);
add(gAddress, LayoutHints.DEFAULT_LARGE_FIELD_HINTS);
 
final Group gElements = new Group("sales.invoice.elements");
gElements.add("(SAISIE_VENTE_FACTURE_ELEMENT)*", LayoutHints.DEFAULT_LIST_HINTS);
40,7 → 40,7
add(gElements, LayoutHints.DEFAULT_LIST_HINTS);
 
final Group gInfos = new Group("sales.invoice.info");
gInfos.add("INFOS", new LayoutHints(true, true, true, true));
gInfos.add("INFOS", new LayoutHints(true, false, true, true, true, false));
add(gInfos);
 
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/ui/SaisieVenteFactureItemTable.java
13,6 → 13,9
package org.openconcerto.erp.core.sales.invoice.ui;
 
import java.util.HashMap;
import java.util.Map;
 
import org.openconcerto.erp.core.common.ui.AbstractVenteArticleItemTable;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLElement;
31,4 → 34,11
public SQLElement getSQLElement() {
return Configuration.getInstance().getDirectory().getElement("SAISIE_VENTE_FACTURE_ELEMENT");
}
public static Map<String, Boolean> map = new HashMap<String, Boolean>();
 
protected Map<String, Boolean> getCustomVisibilityMap() {
return map;
}
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/invoice/component/SaisieVenteFactureSQLComponent.java
24,6 → 24,7
import org.openconcerto.erp.core.finance.accounting.element.ComptePCESQLElement;
import org.openconcerto.erp.core.finance.accounting.element.EcritureSQLElement;
import org.openconcerto.erp.core.finance.payment.component.ModeDeReglementSQLComponent;
import org.openconcerto.erp.core.finance.tax.model.TaxeCache;
import org.openconcerto.erp.core.sales.invoice.element.SaisieVenteFactureSQLElement;
import org.openconcerto.erp.core.sales.invoice.report.VenteFactureXmlSheet;
import org.openconcerto.erp.core.sales.invoice.ui.SaisieVenteFactureItemTable;
288,7 → 289,7
c.fill = GridBagConstraints.NONE;
final ElementComboBox echeancier = new ElementComboBox();
final SQLElement contactElement = Configuration.getInstance().getDirectory().getElement("ECHEANCIER_CCI");
echeancier.init(contactElement, new ComboSQLRequest(contactElement.getComboRequest()));
echeancier.init(contactElement, contactElement.getComboRequest(true));
DefaultGridBagConstraints.lockMinimumSize(echeancier);
this.addView(echeancier, "ID_ECHEANCIER_CCI");
 
481,6 → 482,8
// Frais de port
cFrais.gridheight = 1;
cFrais.gridx = 1;
SQLRequestComboBox boxTaxePort = new SQLRequestComboBox(false, 8);
if (getTable().contains("ID_TAXE_PORT")) {
 
JLabel labelPortHT = new JLabel(getLabelFor("PORT_HT"));
labelPortHT.setHorizontalAlignment(SwingConstants.RIGHT);
489,6 → 492,25
cFrais.gridx++;
panelFrais.add(this.textPortHT, cFrais);
 
JLabel labelTaxeHT = new JLabel(getLabelFor("ID_TAXE_PORT"));
labelTaxeHT.setHorizontalAlignment(SwingConstants.RIGHT);
cFrais.gridx = 1;
cFrais.gridy++;
panelFrais.add(labelTaxeHT, cFrais);
cFrais.gridx++;
panelFrais.add(boxTaxePort, cFrais);
this.addView(boxTaxePort, "ID_TAXE_PORT", REQ);
 
boxTaxePort.addValueListener(new PropertyChangeListener() {
 
@Override
public void propertyChange(PropertyChangeEvent evt) {
// TODO Raccord de méthode auto-généré
totalTTC.updateTotal();
}
});
}
 
// Remise
JLabel labelRemiseHT = new JLabel(getLabelFor("REMISE_HT"));
labelRemiseHT.setHorizontalAlignment(SwingConstants.RIGHT);
526,7 → 548,8
addRequiredSQLObject(fieldService, "T_SERVICE");
JTextField poids = new JTextField();
addSQLObject(poids, "T_POIDS");
totalTTC = new TotalPanel(this.tableFacture, fieldHT, fieldTVA, this.fieldTTC, this.textPortHT, this.textRemiseHT, fieldService, fieldTHA, fieldDevise, poids, null);
totalTTC = new TotalPanel(this.tableFacture, fieldHT, fieldTVA, this.fieldTTC, this.textPortHT, this.textRemiseHT, fieldService, fieldTHA, fieldDevise, poids, null, (getTable().contains(
"ID_TAXE_PORT") ? boxTaxePort : null));
DefaultGridBagConstraints.lockMinimumSize(totalTTC);
cBottom.gridx++;
cBottom.weightx = 1;
1152,6 → 1175,7
SQLRowValues rowVals = new SQLRowValues(fact.getTable());
rowVals.put("ID_CLIENT", row.getInt("ID_CLIENT"));
rowVals.put("NUMERO", NumerotationAutoSQLElement.getNextNumero(SaisieVenteFactureSQLElement.class, new Date()));
rowVals.put("NOM", row.getObject("NOM"));
this.select(rowVals);
}
 
1369,7 → 1393,12
e.printStackTrace();
}
}
 
if (getTable().contains("ID_TAXE_PORT")) {
Integer idFromTaux = TaxeCache.getCache().getIdFromTaux(19.6F);
if (idFromTaux != null) {
vals.put("ID_TAXE_PORT", idFromTaux);
}
}
vals.put("ID_COMPTE_PCE_SERVICE", idCompteVenteService);
System.err.println("Defaults " + vals);
return vals;
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/quote/component/DevisSQLComponent.java
32,6 → 32,7
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.UndefinedRowValuesCache;
import org.openconcerto.sql.sqlobject.ElementComboBox;
import org.openconcerto.sql.sqlobject.JUniqueTextField;
import org.openconcerto.sql.sqlobject.SQLTextCombo;
521,8 → 522,7
if (getTable().getUndefinedID() == SQLRow.NONEXISTANT_ID) {
rowVals.put("ID_ETAT_DEVIS", EtatDevisSQLElement.EN_ATTENTE);
} else {
SQLRow rowUndef = getTable().getRow(getTable().getUndefinedID());
SQLRow foreign = rowUndef.getForeign("ID_ETAT_DEVIS");
SQLRowValues foreign = UndefinedRowValuesCache.getInstance().getDefaultRowValues(getTable());
if (foreign != null && !foreign.isUndefined()) {
rowVals.put("ID_ETAT_DEVIS", foreign.getID());
} else {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/quote/element/DevisSQLElement.java
18,22 → 18,34
import org.openconcerto.erp.core.common.element.ComptaSQLConfElement;
import org.openconcerto.erp.core.sales.invoice.component.SaisieVenteFactureSQLComponent;
import org.openconcerto.erp.core.sales.order.component.CommandeClientSQLComponent;
import org.openconcerto.erp.core.sales.product.element.ReferenceArticleSQLElement;
import org.openconcerto.erp.core.sales.quote.component.DevisSQLComponent;
import org.openconcerto.erp.core.sales.quote.report.DevisXmlSheet;
import org.openconcerto.erp.core.supplychain.stock.element.MouvementStockSQLElement;
import org.openconcerto.erp.model.MouseSheetXmlListeListener;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.element.SQLComponent;
import org.openconcerto.sql.element.SQLElement;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLInjector;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.request.ListSQLRequest;
import org.openconcerto.sql.view.EditFrame;
import org.openconcerto.sql.view.EditPanel;
import org.openconcerto.sql.view.list.IListe;
import org.openconcerto.sql.view.list.RowAction;
import org.openconcerto.utils.CollectionMap;
 
import java.awt.event.ActionEvent;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
 
import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
 
44,10 → 56,209
public DevisSQLElement() {
super(TABLENAME, "un devis", "devis");
 
MouseSheetXmlListeListener l = new MouseSheetXmlListeListener(DevisXmlSheet.class);
getRowActions().addAll(l.getRowActions());
getRowActions().addAll(getDevisRowActions());
}
 
private List<RowAction> getDevisRowActions() {
 
List<RowAction> rowsActions = new ArrayList<RowAction>();
 
// List<RowAction> list = new ArrayList<RowAction>();
// Transfert vers facture
RowAction factureAction = getDevis2FactureAction();
 
rowsActions.add(factureAction);
 
// Voir le document
RowAction actionTransfertCmd = getDevis2CmdFournAction();
rowsActions.add(actionTransfertCmd);
 
// Transfert vers commande
RowAction commandeAction = getDevis2CmdCliAction();
 
rowsActions.add(commandeAction);
 
RowAction accepteEtCmdAction = getAcceptAndCmdClientAction();
rowsActions.add(accepteEtCmdAction);
 
// Marqué accepté
RowAction accepteAction = getAcceptAction();
 
rowsActions.add(accepteAction);
 
// Marqué accepté
RowAction refuseAction = getRefuseAction();
 
rowsActions.add(refuseAction);
 
// // Dupliquer
RowAction cloneAction = getCloneAction();
 
rowsActions.add(cloneAction);
 
MouseSheetXmlListeListener mouseSheetXmlListeListener = new MouseSheetXmlListeListener(DevisXmlSheet.class);
mouseSheetXmlListeListener.setGenerateHeader(true);
mouseSheetXmlListeListener.setShowHeader(true);
 
rowsActions.addAll(mouseSheetXmlListeListener.getRowActions());
 
return rowsActions;
}
 
public RowAction getCloneAction() {
return new RowAction(new AbstractAction("Créer à partir de") {
private EditFrame editFrame;
 
public void actionPerformed(ActionEvent e) {
SQLRow selectedRow = IListe.get(e).getSelectedRow();
 
if (this.editFrame == null) {
SQLElement eltFact = Configuration.getInstance().getDirectory().getElement("DEVIS");
this.editFrame = new EditFrame(eltFact, EditPanel.CREATION);
}
 
((DevisSQLComponent) this.editFrame.getSQLComponent()).loadDevisExistant(selectedRow.getID());
this.editFrame.setVisible(true);
}
}, true) {
public boolean enabledFor(java.util.List<org.openconcerto.sql.model.SQLRowAccessor> selection) {
return (selection != null && selection.size() == 1);
};
};
}
 
public RowAction getRefuseAction() {
return new RowAction(new AbstractAction("Marquer comme refusé") {
public void actionPerformed(ActionEvent e) {
SQLRowValues rowVals = IListe.get(e).getSelectedRow().createEmptyUpdateRow();
rowVals.put("ID_ETAT_DEVIS", EtatDevisSQLElement.REFUSE);
try {
rowVals.update();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
IListe.get(e).getSelectedRow().getTable().fireTableModified(IListe.get(e).getSelectedId());
}
}, false) {
public boolean enabledFor(java.util.List<org.openconcerto.sql.model.SQLRowAccessor> selection) {
if (selection != null && selection.size() == 1) {
if (selection.get(0).getInt("ID_ETAT_DEVIS") == EtatDevisSQLElement.EN_ATTENTE) {
return true;
}
}
return false;
};
};
}
 
public RowAction getAcceptAction() {
return new RowAction(new AbstractAction("Marquer comme accepté") {
public void actionPerformed(ActionEvent e) {
SQLRow selectedRow = IListe.get(e).getSelectedRow();
SQLRowValues rowVals = selectedRow.createEmptyUpdateRow();
rowVals.put("ID_ETAT_DEVIS", EtatDevisSQLElement.ACCEPTE);
try {
rowVals.update();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
selectedRow.getTable().fireTableModified(IListe.get(e).getSelectedId());
}
}, false) {
public boolean enabledFor(java.util.List<org.openconcerto.sql.model.SQLRowAccessor> selection) {
if (selection != null && selection.size() == 1) {
if (selection.get(0).getInt("ID_ETAT_DEVIS") == EtatDevisSQLElement.EN_ATTENTE) {
return true;
}
}
return false;
};
};
}
 
public RowAction getDevis2FactureAction() {
return new RowAction(new AbstractAction("Transfert vers facture") {
public void actionPerformed(ActionEvent e) {
DevisSQLElement elt = (DevisSQLElement) Configuration.getInstance().getDirectory().getElement("DEVIS");
elt.transfertFacture(IListe.get(e).getSelectedRow().getID());
}
}, true) {
public boolean enabledFor(java.util.List<org.openconcerto.sql.model.SQLRowAccessor> selection) {
if (selection != null && selection.size() == 1) {
if (selection.get(0).getInt("ID_ETAT_DEVIS") == EtatDevisSQLElement.ACCEPTE) {
return true;
}
}
return false;
};
};
}
 
public RowAction getDevis2CmdFournAction() {
return new RowAction(new AbstractAction("Transférer en commande") {
public void actionPerformed(ActionEvent e) {
transfertCommande(IListe.get(e).getSelectedRow());
}
}, false) {
public boolean enabledFor(java.util.List<org.openconcerto.sql.model.SQLRowAccessor> selection) {
if (selection != null && selection.size() == 1) {
if (selection.get(0).getInt("ID_ETAT_DEVIS") == EtatDevisSQLElement.ACCEPTE) {
return true;
}
}
return false;
};
};
}
 
public RowAction getDevis2CmdCliAction() {
return new RowAction(new AbstractAction("Transfert vers commande client") {
public void actionPerformed(ActionEvent e) {
DevisSQLElement elt = (DevisSQLElement) Configuration.getInstance().getDirectory().getElement("DEVIS");
elt.transfertCommandeClient(IListe.get(e).getSelectedRow().getID());
}
}, true) {
public boolean enabledFor(java.util.List<org.openconcerto.sql.model.SQLRowAccessor> selection) {
if (selection != null && selection.size() == 1) {
if (selection.get(0).getInt("ID_ETAT_DEVIS") == EtatDevisSQLElement.ACCEPTE) {
return true;
}
}
return false;
};
};
}
 
public RowAction getAcceptAndCmdClientAction() {
return new RowAction(new AbstractAction("Marquer comme accepté et Transfert en commande client") {
public void actionPerformed(ActionEvent e) {
SQLRow selectedRow = IListe.get(e).getSelectedRow();
SQLRowValues rowVals = selectedRow.createEmptyUpdateRow();
rowVals.put("ID_ETAT_DEVIS", EtatDevisSQLElement.ACCEPTE);
try {
rowVals.update();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
selectedRow.getTable().fireTableModified(IListe.get(e).getSelectedId());
DevisSQLElement elt = (DevisSQLElement) Configuration.getInstance().getDirectory().getElement("DEVIS");
elt.transfertCommandeClient(selectedRow.getID());
}
}, false) {
public boolean enabledFor(java.util.List<org.openconcerto.sql.model.SQLRowAccessor> selection) {
if (selection != null && selection.size() == 1) {
if (selection.get(0).getInt("ID_ETAT_DEVIS") == EtatDevisSQLElement.EN_ATTENTE) {
return true;
}
}
return false;
};
};
}
 
protected List<String> getComboFields() {
List<String> l = new ArrayList<String>();
l.add("NUMERO");
54,6 → 265,37
return l;
}
 
private void transfertCommande(SQLRow row) {
DevisItemSQLElement elt = (DevisItemSQLElement) Configuration.getInstance().getDirectory().getElement("DEVIS_ELEMENT");
SQLTable tableCmdElt = Configuration.getInstance().getDirectory().getElement("COMMANDE_ELEMENT").getTable();
SQLElement eltArticle = Configuration.getInstance().getDirectory().getElement("ARTICLE");
List<SQLRow> rows = row.getReferentRows(elt.getTable());
CollectionMap<SQLRow, List<SQLRowValues>> map = new CollectionMap<SQLRow, List<SQLRowValues>>();
for (SQLRow sqlRow : rows) {
// on récupére l'article qui lui correspond
SQLRowValues rowArticle = new SQLRowValues(eltArticle.getTable());
for (SQLField field : eltArticle.getTable().getFields()) {
if (sqlRow.getTable().getFieldsName().contains(field.getName())) {
rowArticle.put(field.getName(), sqlRow.getObject(field.getName()));
}
}
// rowArticle.loadAllSafe(rowEltFact);
int idArticle = ReferenceArticleSQLElement.getIdForCNM(rowArticle, true);
SQLRow rowArticleFind = eltArticle.getTable().getRow(idArticle);
SQLInjector inj = SQLInjector.getInjector(rowArticle.getTable(), tableCmdElt);
SQLRowValues rowValsElt = new SQLRowValues(inj.createRowValuesFrom(rowArticleFind));
rowValsElt.put("ID_STYLE", sqlRow.getObject("ID_STYLE"));
rowValsElt.put("QTE", sqlRow.getObject("QTE"));
rowValsElt.put("T_POIDS", rowValsElt.getLong("POIDS") * rowValsElt.getInt("QTE"));
rowValsElt.put("T_PA_HT", rowValsElt.getLong("PA_HT") * rowValsElt.getInt("QTE"));
rowValsElt.put("T_PA_TTC", rowValsElt.getLong("T_PA_HT") * (rowValsElt.getForeign("ID_TAXE").getFloat("TAUX") / 100.0 + 1.0));
 
map.put(rowArticleFind.getForeignRow("ID_FOURNISSEUR"), rowValsElt);
 
}
MouvementStockSQLElement.createCommandeF(map, row.getForeignRow("ID_TARIF").getForeignRow("ID_DEVISE"));
}
 
protected List<String> getListFields() {
List<String> l = new ArrayList<String>();
l.add("NUMERO");
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/quote/report/DevisTextSheet.java
124,7 → 124,7
}
 
@Override
public String getFileName() {
protected String getName() {
String fileName = "Devis_" + this.row.getString("NUMERO");
return fileName;
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/quote/ui/ListeDesDevisPanel.java
71,7 → 71,6
private SQLElement eltDevis = Configuration.getInstance().getDirectory().getElement("DEVIS");
private SQLElement eltEtatDevis = Configuration.getInstance().getDirectory().getElement("ETAT_DEVIS");
private JButton buttonShow, buttonGen, buttonPrint, buttonFacture, buttonCmd, buttonClone;
protected EditFrame editFrame;
 
public ListeDesDevisPanel() {
this.setLayout(new GridBagLayout());
256,7 → 255,6
// checkButton(id);
// }
// });
addRowActions(pane.getListe(), idFilter);
 
pane.getListe().setOpaque(false);
 
264,213 → 262,10
return pane;
}
 
protected void addRowActions(IListe liste, int etat) {
// List<RowAction> list = new ArrayList<RowAction>();
// Transfert vers facture
RowAction factureAction = new RowAction(new AbstractAction("Transfert vers facture") {
public void actionPerformed(ActionEvent e) {
transfertFacture(IListe.get(e).getSelectedRow());
}
}, true) {
public boolean enabledFor(java.util.List<org.openconcerto.sql.model.SQLRowAccessor> selection) {
if (selection != null && selection.size() == 1) {
if (selection.get(0).getInt("ID_ETAT_DEVIS") == EtatDevisSQLElement.ACCEPTE) {
return true;
}
}
return false;
};
};
 
liste.addIListeAction(factureAction);
 
// Voir le document
RowAction actionTransfertCmd = new RowAction(new AbstractAction("Transférer en commande") {
public void actionPerformed(ActionEvent e) {
transfertCommande(IListe.get(e).getSelectedRow());
}
}, false) {
public boolean enabledFor(java.util.List<org.openconcerto.sql.model.SQLRowAccessor> selection) {
if (selection != null && selection.size() == 1) {
if (selection.get(0).getInt("ID_ETAT_DEVIS") == EtatDevisSQLElement.ACCEPTE) {
return true;
}
}
return false;
};
};
liste.addIListeAction(actionTransfertCmd);
 
// Transfert vers commande
RowAction commandeAction = new RowAction(new AbstractAction("Transfert vers commande client") {
public void actionPerformed(ActionEvent e) {
transfertCommandeClient(IListe.get(e).getSelectedRow());
}
}, true) {
public boolean enabledFor(java.util.List<org.openconcerto.sql.model.SQLRowAccessor> selection) {
if (selection != null && selection.size() == 1) {
if (selection.get(0).getInt("ID_ETAT_DEVIS") == EtatDevisSQLElement.ACCEPTE) {
return true;
}
}
return false;
};
};
 
liste.addIListeAction(commandeAction);
 
RowAction accepteEtCmdAction = new RowAction(new AbstractAction("Marquer comme accepté et Transfert en commande client") {
public void actionPerformed(ActionEvent e) {
SQLRow selectedRow = IListe.get(e).getSelectedRow();
SQLRowValues rowVals = selectedRow.createEmptyUpdateRow();
rowVals.put("ID_ETAT_DEVIS", EtatDevisSQLElement.ACCEPTE);
try {
rowVals.update();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
selectedRow.getTable().fireTableModified(IListe.get(e).getSelectedId());
transfertCommandeClient(selectedRow);
}
}, false) {
public boolean enabledFor(java.util.List<org.openconcerto.sql.model.SQLRowAccessor> selection) {
if (selection != null && selection.size() == 1) {
if (selection.get(0).getInt("ID_ETAT_DEVIS") == EtatDevisSQLElement.EN_ATTENTE) {
return true;
}
}
return false;
};
};
liste.addIListeAction(accepteEtCmdAction);
 
// Marqué accepté
RowAction accepteAction = new RowAction(new AbstractAction("Marquer comme accepté") {
public void actionPerformed(ActionEvent e) {
SQLRowValues rowVals = IListe.get(e).getSelectedRow().createEmptyUpdateRow();
rowVals.put("ID_ETAT_DEVIS", EtatDevisSQLElement.ACCEPTE);
try {
rowVals.update();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
IListe.get(e).getSelectedRow().getTable().fireTableModified(IListe.get(e).getSelectedId());
}
}, false) {
public boolean enabledFor(java.util.List<org.openconcerto.sql.model.SQLRowAccessor> selection) {
if (selection != null && selection.size() == 1) {
if (selection.get(0).getInt("ID_ETAT_DEVIS") == EtatDevisSQLElement.EN_ATTENTE) {
return true;
}
}
return false;
};
};
 
liste.addIListeAction(accepteAction);
 
// Marqué accepté
RowAction refuseAction = new RowAction(new AbstractAction("Marquer comme refusé") {
public void actionPerformed(ActionEvent e) {
SQLRowValues rowVals = IListe.get(e).getSelectedRow().createEmptyUpdateRow();
rowVals.put("ID_ETAT_DEVIS", EtatDevisSQLElement.REFUSE);
try {
rowVals.update();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
IListe.get(e).getSelectedRow().getTable().fireTableModified(IListe.get(e).getSelectedId());
}
}, false) {
public boolean enabledFor(java.util.List<org.openconcerto.sql.model.SQLRowAccessor> selection) {
if (selection != null && selection.size() == 1) {
if (selection.get(0).getInt("ID_ETAT_DEVIS") == EtatDevisSQLElement.EN_ATTENTE) {
return true;
}
}
return false;
};
};
 
liste.addIListeAction(refuseAction);
 
// // Dupliquer
RowAction cloneAction = new RowAction(new AbstractAction("Créer à partir de") {
public void actionPerformed(ActionEvent e) {
SQLRow selectedRow = IListe.get(e).getSelectedRow();
 
if (ListeDesDevisPanel.this.editFrame == null) {
SQLElement eltFact = Configuration.getInstance().getDirectory().getElement("DEVIS");
ListeDesDevisPanel.this.editFrame = new EditFrame(eltFact, EditPanel.CREATION);
}
 
((DevisSQLComponent) ListeDesDevisPanel.this.editFrame.getSQLComponent()).loadDevisExistant(selectedRow.getID());
ListeDesDevisPanel.this.editFrame.setVisible(true);
}
}, true) {
public boolean enabledFor(java.util.List<org.openconcerto.sql.model.SQLRowAccessor> selection) {
return (selection != null && selection.size() == 1);
};
};
 
liste.addIListeAction(cloneAction);
}
 
/**
* Transfert en facture
*
* @param row
*/
private void transfertFacture(SQLRow row) {
DevisSQLElement elt = (DevisSQLElement) Configuration.getInstance().getDirectory().getElement("DEVIS");
elt.transfertFacture(row.getID());
}
 
/**
* Transfert en Commande
*
* @param row
*/
private void transfertCommandeClient(SQLRow row) {
 
DevisSQLElement elt = (DevisSQLElement) Configuration.getInstance().getDirectory().getElement("DEVIS");
elt.transfertCommandeClient(row.getID());
}
 
private void transfertCommande(SQLRow row) {
DevisItemSQLElement elt = (DevisItemSQLElement) Configuration.getInstance().getDirectory().getElement("DEVIS_ELEMENT");
SQLTable tableCmdElt = Configuration.getInstance().getDirectory().getElement("COMMANDE_ELEMENT").getTable();
SQLElement eltArticle = Configuration.getInstance().getDirectory().getElement("ARTICLE");
List<SQLRow> rows = row.getReferentRows(elt.getTable());
CollectionMap<SQLRow, List<SQLRowValues>> map = new CollectionMap<SQLRow, List<SQLRowValues>>();
for (SQLRow sqlRow : rows) {
// on récupére l'article qui lui correspond
SQLRowValues rowArticle = new SQLRowValues(eltArticle.getTable());
for (SQLField field : eltArticle.getTable().getFields()) {
if (sqlRow.getTable().getFieldsName().contains(field.getName())) {
rowArticle.put(field.getName(), sqlRow.getObject(field.getName()));
}
}
// rowArticle.loadAllSafe(rowEltFact);
int idArticle = ReferenceArticleSQLElement.getIdForCNM(rowArticle, true);
SQLRow rowArticleFind = eltArticle.getTable().getRow(idArticle);
SQLInjector inj = SQLInjector.getInjector(rowArticle.getTable(), tableCmdElt);
SQLRowValues rowValsElt = new SQLRowValues(inj.createRowValuesFrom(rowArticleFind));
rowValsElt.put("ID_STYLE", sqlRow.getObject("ID_STYLE"));
rowValsElt.put("QTE", sqlRow.getObject("QTE"));
rowValsElt.put("T_POIDS", rowValsElt.getLong("POIDS") * rowValsElt.getInt("QTE"));
rowValsElt.put("T_PA_HT", rowValsElt.getLong("PA_HT") * rowValsElt.getInt("QTE"));
rowValsElt.put("T_PA_TTC", rowValsElt.getLong("T_PA_HT") * (rowValsElt.getForeign("ID_TAXE").getFloat("TAUX") / 100.0 + 1.0));
 
map.put(rowArticleFind.getForeignRow("ID_FOURNISSEUR"), rowValsElt);
 
}
MouvementStockSQLElement.createCommandeF(map, row.getForeignRow("ID_TARIF").getForeignRow("ID_DEVISE"));
}
 
public Map<Integer, ListeAddPanel> getListePanel() {
return this.map;
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/product/component/ReferenceArticleSQLComponent.java
66,7 → 66,6
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.event.DocumentEvent;
87,8 → 86,8
private PropertyChangeListener taxeListener;
final ElementComboBox comboSelTaxe = new ElementComboBox(false, 25);
final ElementComboBox comboSelModeVente = new ElementComboBox(false, 25);
private JLabel labelMetriqueHA1 = new JLabel(getLabelFor("PRIX_METRIQUE_HA_1"));
private JLabel labelMetriqueVT1 = new JLabel(getLabelFor("PRIX_METRIQUE_VT_1"));
private JLabel labelMetriqueHA1 = new JLabel(getLabelFor("PRIX_METRIQUE_HA_1"), SwingConstants.RIGHT);
private JLabel labelMetriqueVT1 = new JLabel(getLabelFor("PRIX_METRIQUE_VT_1"), SwingConstants.RIGHT);
 
ArticleDesignationTable tableDes = new ArticleDesignationTable();
ArticleTarifTable tableTarifVente = new ArticleTarifTable(this);
299,8 → 298,10
if (gestionUV) {
c.gridy++;
c.gridx = 0;
this.add(new JLabel(getLabelFor("ID_UNITE_VENTE")), c);
c.weightx = 0;
this.add(new JLabel(getLabelFor("ID_UNITE_VENTE"), SwingConstants.RIGHT), c);
c.gridx++;
c.weightx = 1;
ElementComboBox boxUnite = new ElementComboBox();
this.add(boxUnite, c);
this.addView(boxUnite, "ID_UNITE_VENTE");
348,7 → 349,7
 
c.gridy++;
c.weighty = 0.3;
JTextArea infos = new JTextArea();
ITextArea infos = new ITextArea();
c.fill = GridBagConstraints.BOTH;
this.add(infos, c);
 
905,7 → 906,7
private void addModeVenteAvance(GridBagConstraints c) {
DefaultProps props = DefaultNXProps.getInstance();
JSeparator sep = new JSeparator();
JLabel labelDetails = new JLabel("Article détaillé");
JLabel labelDetails = new JLabel("Article détaillé", SwingConstants.RIGHT);
c.gridx = 0;
c.gridy++;
c.weightx = 0;
921,13 → 922,14
c.weightx = 0;
c.gridx = 0;
c.gridy++;
this.add(new JLabel(getLabelFor("ID_MODE_VENTE_ARTICLE")), c);
 
this.add(new JLabel(getLabelFor("ID_MODE_VENTE_ARTICLE"), SwingConstants.RIGHT), c);
c.weightx = 1;
c.gridx++;
this.add(this.comboSelModeVente, c);
 
// Prix metrique
c.gridx = 0;
c.weightx = 0;
c.gridy++;
this.add(this.labelMetriqueHA1, c);
c.gridx++;
943,7 → 945,7
 
// Metrique 1
c.weightx = 0;
JLabel labelMetrique1 = new JLabel(getLabelFor("VALEUR_METRIQUE_1"));
JLabel labelMetrique1 = new JLabel(getLabelFor("VALEUR_METRIQUE_1"), SwingConstants.RIGHT);
c.gridx = 0;
c.gridy++;
this.add(labelMetrique1, c);
958,7 → 960,7
this.textValMetrique1.setVisible(bMetrique1 == null || bMetrique1.booleanValue());
 
// Metrique 2
JLabel labelMetrique2 = new JLabel(getLabelFor("VALEUR_METRIQUE_2"));
JLabel labelMetrique2 = new JLabel(getLabelFor("VALEUR_METRIQUE_2"), SwingConstants.RIGHT);
c.gridx = 0;
c.gridy++;
c.weightx = 0;
974,7 → 976,7
this.textValMetrique2.setVisible(bMetrique2 == null || bMetrique2.booleanValue());
 
// Metrique 3
JLabel labelMetrique3 = new JLabel(getLabelFor("VALEUR_METRIQUE_3"));
JLabel labelMetrique3 = new JLabel(getLabelFor("VALEUR_METRIQUE_3"), SwingConstants.RIGHT);
c.gridx = 0;
c.gridy++;
c.weightx = 0;
990,7 → 992,7
 
// Article détaillé
JSeparator sep2 = new JSeparator();
JLabel labelPiece = new JLabel("Article pièce");
JLabel labelPiece = new JLabel("Article pièce", SwingConstants.RIGHT);
c.gridx = 0;
c.gridy++;
c.weightx = 0;
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/CategorieSelector.java
66,17 → 66,20
 
@Override
public void mousePressed(MouseEvent e) {
final Categorie prev = CategorieSelector.this.previous;
CategorieSelector.this.model.setRoot(prev);
// User pressed "Previous" button on category
final Categorie newCategory = CategorieSelector.this.previous;
CategorieSelector.this.model.setRoot(newCategory);
CategorieSelector.this.list.clearSelection();
if (prev == null) {
if (newCategory == null) {
CategorieSelector.this.comp.setTitle("Catégories");
CategorieSelector.this.comp.setPrevious(false);
articleModel.setCategorie(null);
CategorieSelector.this.previous = null;
} else {
CategorieSelector.this.comp.setTitle(prev.getName());
CategorieSelector.this.comp.setTitle(newCategory.getName());
CategorieSelector.this.comp.setPrevious(true);
CategorieSelector.this.previous = newCategory.getParent();
}
articleModel.setCategorie(newCategory);
}
 
});
84,9 → 87,9
 
@Override
public void valueChanged(ListSelectionEvent e) {
Object sel = this.list.getSelectedValue();
final Object sel = this.list.getSelectedValue();
if (sel != null && !e.getValueIsAdjusting()) {
Categorie c = (Categorie) sel;
final Categorie c = (Categorie) sel;
if (!c.getSubCategories().isEmpty()) {
// Descend la hierarchie
this.previous = this.model.getRoot();
104,10 → 107,9
public void caisseStateChanged() {
final Article articleSelected = this.controller.getArticleSelected();
if (articleSelected != null) {
Categorie c = articleSelected.getCategorie();
final Categorie c = articleSelected.getCategorie();
if (c.getParent() != null) {
this.previous = c.getParent().getParent();
 
this.model.setRoot(c.getParent());
this.comp.setTitle(c.getParent().getName());
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/ConfigCaissePanel.java
22,6 → 22,7
import org.openconcerto.sql.model.SQLRowListRSH;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLServer;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.JLabelBold;
 
293,19 → 294,16
DBSystemRoot r = server.getSystemRoot(config.getSystemRoot());
DBRoot root = r.getRoot("Common");
// Sociétés
SQLSelect sel = new SQLSelect(root.getBase());
sel.addSelectStar(root.getTable("SOCIETE_COMMON"));
sel.setWhere("SOCIETE_COMMON.ID", "=", id);
 
final List<SQLRow> societes = SQLRowListRSH.execute(sel);
final SQLTable societeT = root.getTable("SOCIETE_COMMON");
final SQLRow societe = societeT.getValidRow(id);
server.destroy();
if (societes.size() > 0) {
final String name = societes.get(0).getString("DATABASE_NAME");
if (societe != null) {
final String name = societe.getString("DATABASE_NAME");
server = config.createServer(name);
r = server.getSystemRoot(config.getSystemRoot());
root = r.getRoot(name);
// Caisses
sel = new SQLSelect(root.getBase());
SQLSelect sel = new SQLSelect(root.getBase());
sel.addSelectStar(root.getTable("CAISSE"));
final List<SQLRow> caisses = SQLRowListRSH.execute(sel);
server.destroy();
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/CategorieModel.java
13,11 → 13,11
package org.openconcerto.erp.core.sales.pos.ui;
 
 
 
import org.openconcerto.erp.core.sales.pos.model.Categorie;
 
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
 
import javax.swing.ListModel;
34,18 → 34,15
@Override
public void addListDataListener(ListDataListener l) {
listeners.add(l);
 
}
 
@Override
public Object getElementAt(int index) {
 
return items.get(index);
}
 
@Override
public int getSize() {
// TODO Auto-generated method stub
return items.size();
}
 
63,6 → 60,12
} else {
this.items.addAll(c.getSubCategories());
}
Collections.sort(items, new Comparator<Categorie>() {
@Override
public int compare(Categorie o1, Categorie o2) {
return o1.getName().compareTo(o2.getName());
}
});
fire();
}
 
73,7 → 76,6
}
 
public Categorie getRoot() {
 
return this.categorie;
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/ListeDesTicketsPanel.java
179,14 → 179,11
}
Object selectedValue = ticketList.getSelectedValue();
int selectedIndex = l.getSelectedIndex();
System.out.println("ListeDesTicketsPanel.valueChanged():" + selectedIndex);
if (selectedIndex == 0) {
// Imprimer
 
if (selectedValue != null) {
TicketPrinter prt = Caisse.getTicketPrinter();
((Ticket) selectedValue).print(prt);
 
}
} else if (selectedIndex == 1) {
// Effacer
194,12 → 191,12
ticketLlistModel.removeElement(selectedValue);
ticketList.clearSelection();
((Ticket) selectedValue).deleteTicket();
 
}
} else if (selectedIndex == 3) {
// Retour
frame.showMenu();
}
l.clearSelection();
}
 
@Override
223,8 → 220,6
public void setSelectedTicket(Object selectedValue) {
ticketP.clear();
if (selectedValue != null) {
System.err.println("ListeDesTeicketsPanel.valueChanged():" + selectedValue);
 
((Ticket) selectedValue).print(ticketP);
try {
ticketP.printBuffer();
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/CaisseControler.java
61,14 → 61,14
}
 
void setArticleSelected(Article a) {
System.out.println("CaisseControler.setArticleSelected() : " + a);
if (a != articleSelected) {
this.articleSelected = a;
this.paiementSelected = null;
fire();
}
}
 
void setPaiementSelected(Paiement p) {
System.out.println("CaisseControler.setPaiementSelected() : " + p);
this.paiementSelected = p;
this.articleSelected = null;
fire();
114,7 → 114,6
 
public void clearPaiement(Paiement paiement) {
if (this.p1.equals(paiement) || this.p2.equals(paiement) || this.p3.equals(paiement)) {
 
paiement.setMontantInCents(0);
}
fire();
123,13 → 122,11
public void setPaiementValue(Paiement paiement, int v) {
paiement.setMontantInCents(v);
fire();
 
}
 
// Totaux
public int getTotal() {
return this.t.getTotal();
 
}
 
public int getPaidTotal() {
144,7 → 141,6
 
public int getItemCount(Article article) {
return this.t.getItemCount(article);
 
}
 
public void clearArticle(Article article) {
227,7 → 223,6
 
@Override
public void keyReceived(KeyEvent ee) {
// TODO Auto-generated method stub
 
}
 
270,7 → 265,7
public void printTicket() {
if (this.t.getTotal() > 0) {
if (this.getPaidTotal() >= this.getTotal()) {
TicketPrinter prt = Caisse.getTicketPrinter();
final TicketPrinter prt = Caisse.getTicketPrinter();
t.print(prt);
} else {
System.err.println("Ticket not printed because not paid");
282,9 → 277,8
 
public void openDrawer() {
try {
TicketPrinter prt = Caisse.getTicketPrinter();
final TicketPrinter prt = Caisse.getTicketPrinter();
prt.openDrawer();
 
} catch (Exception e) {
e.printStackTrace();
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/ArticleModel.java
55,8 → 55,6
this.items.clear();
if (c != null) {
this.items.addAll(c.getArticles());
} else {
this.items.clear();
}
fire();
}
68,7 → 66,6
}
 
public Categorie getRoot() {
 
return this.categorie;
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/CaisseMenuPanel.java
19,6 → 19,7
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
26,6 → 27,7
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D;
import java.util.Set;
 
import javax.swing.ImageIcon;
import javax.swing.JLabel;
107,6 → 109,17
case 5:
// Fermeture
frame.dispose();
Frame[] l = Frame.getFrames();
for (int i = 0; i < l.length; i++) {
Frame f = l[i];
System.err.println(f.getName() + " " + f + " Displayable: " + f.isDisplayable() + " Valid: " + f.isValid() + " Active: " + f.isActive());
}
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for (Thread thread : threadSet) {
if (!thread.isDaemon()) {
System.err.println(thread.getName() + " " + thread.getId() + " not daemon");
}
}
break;
default:
break;
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/ui/ArticleSelector.java
60,7 → 60,6
list = new ScrollableList(model) {
@Override
public void paint(Graphics g) {
 
super.paint(g);
g.setColor(Color.GRAY);
g.drawLine(0, 0, 0, this.getHeight());
89,14 → 88,33
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Article article = (Article) object;
String label = article.getName();
if (label.length() > 14) {
label = label.substring(0, 14) + "...";
final int MAX_WIDTH = 18;
if (label.length() > MAX_WIDTH * 2) {
label = label.substring(0, MAX_WIDTH * 2) + "...";
}
String label2 = null;
if (label.length() > MAX_WIDTH) {
String t = label.substring(0, MAX_WIDTH).trim();
int lastSpace = t.lastIndexOf(' ');
if (lastSpace <= 0) {
lastSpace = MAX_WIDTH;
}
label2 = label.substring(lastSpace).trim();
label = label.substring(0, lastSpace).trim();
if (label2.length() > MAX_WIDTH) {
label2 = label2.substring(0, MAX_WIDTH) + "...";
}
}
 
String euro = TicketCellRenderer.centsToString(article.getPriceInCents()) + "€";
 
int wEuro = (int) g.getFontMetrics().getStringBounds(euro, g).getWidth();
if (label2 == null) {
g.drawString(label, 10, posY + 39);
} else {
g.drawString(label, 10, posY + 26);
g.drawString(label2, 10, posY + 52);
}
g.drawString(euro, getWidth() - 5 - wEuro, posY + 39);
 
}
110,17 → 128,13
list.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
 
int nb = e.getClickCount();
System.out.println(nb);
if (nb > 1) {
Object sel = list.getSelectedValue();
if (sel != null) {
Article article = (Article) sel;
controller.incrementArticle(article);
 
controller.setArticleSelected(article);
 
}
}
}
133,9 → 147,7
if (sel != null && !e.getValueIsAdjusting()) {
Article article = (Article) sel;
controller.addArticle(article);
 
controller.setArticleSelected(article);
 
}
}
 
147,11 → 159,8
public void caisseStateChanged() {
 
final Article articleSelected = controller.getArticleSelected();
System.out.println("ArticleSelector.caisseStateChanged():" + articleSelected);
if (articleSelected == null) {
list.clearSelection();
return;
 
}
 
Object selectedValue = null;
158,7 → 167,6
try {
selectedValue = list.getSelectedValue();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
if (articleSelected != null && !articleSelected.equals(selectedValue)) {
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/model/Categorie.java
13,8 → 13,10
package org.openconcerto.erp.core.sales.pos.model;
 
 
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
 
public class Categorie {
32,13 → 34,13
 
public Categorie(String string, boolean top) {
this.name = string;
if (top)
if (top) {
topLevelCategories.add(this);
}
}
 
@Override
public String toString() {
 
return name;
}
 
49,7 → 51,6
 
private void setParentCategorie(Categorie categorie) {
this.parent = categorie;
 
}
 
public Categorie getParent() {
61,12 → 62,10
}
 
public static List<Categorie> getTopLevelCategories() {
 
return topLevelCategories;
}
 
public List<Categorie> getSubCategories() {
 
return l;
}
 
75,15 → 74,17
}
 
public List<Article> getArticles() {
System.out.println("\nArticles de " + this.getName());
List<Article> result = new ArrayList<Article>();
final List<Article> result = new ArrayList<Article>();
result.addAll(articles);
for (Categorie c : l) {
System.out.println("\nArticles de sous cat:" + c.getName());
result.addAll(c.getArticles());
}
 
System.out.println(result);
Collections.sort(result, new Comparator<Article>() {
@Override
public int compare(Article o1, Article o2) {
return o1.getName().compareTo(o2.getName());
}
});
return result;
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/model/Ticket.java
89,7 → 89,7
 
// Loading file
File dir = t.getOutputDir();
File file = new File(dir, code.replace(' ', '_') + ".xml");
File file = new File(dir, getFileName(code));
if (!file.exists()) {
return null;
}
159,6 → 159,10
 
}
 
private static String getFileName(String code) {
return code.replace(' ', '_') + ".xml";
}
 
public Ticket(int caisse) {
this.caisseNumber = caisse;
this.date = Calendar.getInstance().getTime();
177,7 → 181,6
private void initNumber() {
if (!inited) {
this.number = 1;
 
String[] files = getCompatibleFileNames();
for (int i = 0; i < files.length; i++) {
String name = files[i];
187,25 → 190,14
if (n >= this.number) {
this.number = n + 1;
}
 
}
 
}
}
 
public String[] getCompatibleFileNames() {
File dir = getOutputDir();
// Calendar cal = Calendar.getInstance();
//
// int j = cal.get(Calendar.DAY_OF_MONTH);
// int m = cal.get(Calendar.MONTH) + 1;
// int a = cal.get(Calendar.YEAR);
// String code = "";
// code += format(2, this.getCaisseNumber()) + "_";
// code += format(2, j) + format(2, m) + format(4, a) + "_";
// final String codeStart = code;
final File dir = getOutputDir();
final String codeStart = getPrefixCode();
String[] files = dir.list(new FilenameFilter() {
final String[] files = dir.list(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.startsWith(codeStart) && name.endsWith(".xml");
227,15 → 219,6
}
 
public String getCode() {
// Calendar cal = Calendar.getInstance();
// cal.setTime(this.date);
// int j = cal.get(Calendar.DAY_OF_MONTH);
// int m = cal.get(Calendar.MONTH) + 1;
// int a = cal.get(Calendar.YEAR) - 2000;
// String code = "";
// code += format(2, this.getCaisseNumber());
// code += format(2, j) + format(2, m) + format(2, a);
// code += format(5, this.getNumber());
String code = getPrefixCode();
code += format(5, this.getNumber());
return code;
262,7 → 245,7
 
// Hierarchie: 2010/04/05/01_05042010_00002.xml
File dir = getOutputDir();
File f = new File(dir, getCode().replace(' ', '_') + ".xml");
File f = new File(dir, getFileName(getCode()));
Element topLevel = new Element("ticket");
topLevel.setAttribute(new Attribute("code", this.getCode()));
topLevel.setAttribute("hour", String.valueOf(hour));
303,7 → 286,9
}
try {
final XMLOutputter out = new XMLOutputter(Format.getPrettyFormat());
out.output(topLevel, new FileOutputStream(f));
final FileOutputStream fileOutputStream = new FileOutputStream(f);
out.output(topLevel, fileOutputStream);
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
598,9 → 583,8
 
public void deleteTicket() {
File dir = this.getOutputDir();
String name = this.getCode().replace(' ', '_') + ".xml";
String name = getFileName(this.getCode());
File f = new File(dir, name);
f.renameTo(new File(dir, name + "_deleted"));
 
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/sales/pos/Caisse.java
334,10 → 334,17
final String[] names = t.getCompatibleFileNames();
 
for (int i = 0; i < names.length; i++) {
final String code = names[i].substring(0, 17);
String code = names[i];
int indexExtension = code.indexOf(".xml");
if (indexExtension > 0) {
code = code.substring(0, indexExtension);
}
final Ticket ticket = Ticket.getTicketFromCode(code);
 
if (ticket != null) {
l.add(ticket);
}
}
return l;
}
 
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/ui/TotalPanel.java
15,11 → 15,12
 
import org.openconcerto.erp.config.ComptaPropsConfiguration;
import org.openconcerto.erp.core.finance.tax.model.TaxeCache;
import org.openconcerto.erp.model.PrixHT;
import org.openconcerto.erp.preferences.DefaultNXProps;
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLRow;
import org.openconcerto.sql.model.SQLRowAccessor;
import org.openconcerto.sql.sqlobject.SQLRequestComboBox;
import org.openconcerto.sql.view.list.RowValuesTable;
import org.openconcerto.sql.view.list.RowValuesTableModel;
import org.openconcerto.sql.view.list.SQLTableElement;
37,6 → 38,7
import java.math.MathContext;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
 
import javax.swing.JLabel;
import javax.swing.JPanel;
67,11 → 69,18
private int columnIndexEchHT = -1;
private int columnIndexEchTTC = -1;
SQLTableElement ha;
private SQLRequestComboBox selPortTVA;
 
public TotalPanel(AbstractArticleItemTable articleItemTable, DeviseField textTotalHT, DeviseField textTotalTVA, DeviseField textTotalTTC, DeviseField textPortHT, DeviseField textRemiseHT,
DeviseField textService, DeviseField textTotalHA, DeviseField textTotalDevise, JTextField textTotalPoids, JPanel tableEchantillon) {
this(articleItemTable, textTotalHT, textTotalTVA, textTotalTTC, textPortHT, textRemiseHT, textService, textTotalHA, textTotalDevise, textTotalPoids, tableEchantillon, null);
}
 
public TotalPanel(AbstractArticleItemTable articleItemTable, DeviseField textTotalHT, DeviseField textTotalTVA, DeviseField textTotalTTC, DeviseField textPortHT, DeviseField textRemiseHT,
DeviseField textService, DeviseField textTotalHA, DeviseField textTotalDevise, JTextField textTotalPoids, JPanel tableEchantillon, SQLRequestComboBox selPortTva) {
 
super();
this.selPortTVA = selPortTva;
this.ha = (articleItemTable.getPrebilanElement() == null) ? articleItemTable.getHaElement() : articleItemTable.getPrebilanElement();
this.supp = new PropertyChangeSupport(this);
this.table = articleItemTable.getRowValuesTable();
513,17 → 522,51
}
 
realTotalHT = totalHT + valPortHT - valRemiseHT;
long portTTC = new PrixHT(valPortHT).calculLongTTC(0.196F);
long remiseTTC = new PrixHT(valRemiseHT).calculLongTTC(0.196F);
// long portTTC = new PrixHT(valPortHT).calculLongTTC(0.196F);
 
// TVA Port inclus
if (this.selPortTVA != null) {
 
SQLRow tvaPort = this.selPortTVA.getSelectedRow();
if (tvaPort != null) {
// Total TVA
if (mapHtTVA.get(tvaPort) == null) {
mapHtTVA.put(tvaPort, valPortHT);
} else {
Long l = mapHtTVA.get(tvaPort);
mapHtTVA.put(tvaPort, l + valPortHT);
}
}
}
 
long realTotalTVA = 0;
// Déduction de la remise pour la TVA
long totalHTAvantRemise = totalHT + valPortHT;
long remiseToApply = valRemiseHT;
if (remiseToApply > 0) {
Set<SQLRowAccessor> setHtTVA = mapHtTVA.keySet();
int i = 0;
for (SQLRowAccessor row : mapHtTVA.keySet()) {
Long ht = mapHtTVA.get(row);
i++;
if (i == setHtTVA.size()) {
mapHtTVA.put(row, ht - remiseToApply);
} else {
// Prorata
long r = new BigDecimal(ht).divide(new BigDecimal(totalHTAvantRemise), MathContext.DECIMAL128).multiply(new BigDecimal(valRemiseHT)).setScale(0, BigDecimal.ROUND_HALF_UP)
.longValue();
mapHtTVA.put(row, ht - r);
remiseToApply -= r;
}
}
}
for (SQLRowAccessor row : mapHtTVA.keySet()) {
BigDecimal d = new BigDecimal(TaxeCache.getCache().getTauxFromId(row.getID()));
BigDecimal result = d.multiply(new BigDecimal(mapHtTVA.get(row)), MathContext.DECIMAL128).movePointLeft(2);
realTotalTVA += result.setScale(0, BigDecimal.ROUND_HALF_UP).longValue();
}
 
long realTotalTTC = totalHT + realTotalTVA + portTTC - remiseTTC;
long realTotalTTC = realTotalHT + realTotalTVA;
 
if (this.textTotalDevise != null) {
this.textTotalDevise.setText(GestionDevise.currencyToString(totalDevise));
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/ui/ReminderDialog.java
New file
0,0 → 1,109
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.erp.core.common.ui;
 
import org.openconcerto.sql.preferences.UserProps;
import org.openconcerto.ui.DefaultGridBagConstraints;
 
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
 
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
 
public class ReminderDialog {
 
public static void showMessage(final String title, final String text, final String propertyId) {
assert SwingUtilities.isEventDispatchThread();
final boolean hideMessage = UserProps.getInstance().getBooleanValue("hide." + propertyId, false);
if (!hideMessage) {
final JDialog d = new JDialog();
d.setTitle(title);
final String[] parts = text.split("\n");
final JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
final GridBagConstraints c = new DefaultGridBagConstraints();
c.fill = GridBagConstraints.NONE;
c.gridwidth = 2;
for (int i = 0; i < parts.length; i++) {
panel.add(new JLabel(parts[i]), c);
c.gridy++;
}
c.gridwidth = 1;
c.gridx = 0;
c.weightx = 1;
c.weighty = 1;
c.anchor = GridBagConstraints.SOUTHWEST;
final JCheckBox checkbox = new JCheckBox("ne plus afficher cette information");
panel.add(checkbox, c);
c.gridx++;
c.anchor = GridBagConstraints.SOUTHEAST;
final JButton buttonOk = new JButton("OK");
panel.add(buttonOk, c);
d.setContentPane(panel);
d.pack();
d.setLocationRelativeTo(null);
d.setResizable(false);
d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
d.setVisible(true);
 
buttonOk.addActionListener(new ActionListener() {
 
@Override
public void actionPerformed(ActionEvent e) {
final boolean selected = checkbox.isSelected();
final SwingWorker<Object, Object> worker = new SwingWorker<Object, Object>() {
 
@Override
protected Object doInBackground() throws Exception {
if (selected) {
UserProps.getInstance().setProperty("hide." + propertyId, "true");
UserProps.getInstance().store();
}
return null;
}
 
};
worker.execute();
d.dispose();
 
}
});
 
}
 
}
 
public static void resetMessageStates() {
assert !SwingUtilities.isEventDispatchThread();
final List<Object> keys = new ArrayList<Object>();
keys.addAll(UserProps.getInstance().getProps().keySet());
for (Object object : keys) {
final String key = object.toString();
if (key.startsWith("hide.")) {
UserProps.getInstance().setProperty(key, null);
}
}
UserProps.getInstance().store();
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/ui/AbstractArticleItemTable.java
43,6 → 43,7
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
 
public abstract class AbstractArticleItemTable extends JPanel {
protected RowValuesTable table;
99,6 → 100,7
c.weightx = 1;
c.weighty = 1;
final JScrollPane comp = new JScrollPane(this.table);
comp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
this.add(comp, c);
this.table.setDefaultRenderer(Long.class, new RowValuesTableRenderer());
}
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/ui/AbstractAchatArticleItemTable.java
34,6 → 34,7
import org.openconcerto.sql.view.list.RowValuesTable;
import org.openconcerto.sql.view.list.RowValuesTableModel;
import org.openconcerto.sql.view.list.SQLTableElement;
import org.openconcerto.sql.view.list.ValidStateChecker;
 
import java.math.BigDecimal;
import java.math.MathContext;
182,6 → 183,7
// Total HT
this.totalHT = new SQLTableElement(e.getTable().getField("T_PA_HT"), Long.class, new DeviseCellEditor());
this.totalHT.setRenderer(new DeviseNiceTableCellRenderer());
this.totalHT.setEditable(false);
list.add(this.totalHT);
// Total TTC
this.tableElementTotalTTC = new SQLTableElement(e.getTable().getField("T_PA_TTC"), Long.class, new DeviseCellEditor());
257,7 → 259,7
}
 
this.m3 = new AutoCompletionManager(tableElementArticle, ((ComptaPropsConfiguration) Configuration.getInstance()).getSQLBaseSociete().getField("ARTICLE.NOM"), this.table,
this.table.getRowValuesTableModel(), ITextWithCompletion.MODE_CONTAINS, true, true) {
this.table.getRowValuesTableModel(), ITextWithCompletion.MODE_CONTAINS, true, true, new ValidStateChecker()) {
@Override
protected Object getValueFrom(SQLRow row, String field) {
Object res = tarifCompletion(row, field);
396,7 → 398,8
this.tableElementPoidsTotal.setModifier(new CellDynamicModifier() {
public Object computeValueFrom(SQLRowValues row) {
System.err.println("Calcul du poids total ");
Number f = (Number) row.getObject("POIDS");
// Number f = (Number) row.getObject("POIDS");
Number f = (row.getObject("POIDS") == null) ? 0 : (Number) row.getObject("POIDS");
int qte = Integer.parseInt(row.getObject("QTE").toString());
 
// return new Float(f.floatValue() * qte);
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/ui/AbstractVenteArticleItemTable.java
37,6 → 37,7
import org.openconcerto.sql.view.list.RowValuesTable;
import org.openconcerto.sql.view.list.RowValuesTableModel;
import org.openconcerto.sql.view.list.SQLTableElement;
import org.openconcerto.sql.view.list.ValidStateChecker;
import org.openconcerto.utils.ExceptionHandler;
 
import java.math.BigDecimal;
403,6 → 404,8
this.totalHT.setRenderer(new DeviseNiceTableCellRenderer());
list.add(this.totalHT);
// Total TTC
// FIXME add a modifier -> T_TTC modify P_VT_METRIQUE_1 + fix CellDynamicModifier not fire
// if value not changed
this.tableElementTotalTTC = new SQLTableElement(e.getTable().getField("T_PV_TTC"), Long.class, new DeviseCellEditor());
this.tableElementTotalTTC.setRenderer(new DeviseNiceTableCellRenderer());
list.add(this.tableElementTotalTTC);
492,7 → 495,7
m2.setWhere(new Where(sqlTableArticle.getField("OBSOLETE"), "=", Boolean.FALSE));
 
final AutoCompletionManager m3 = new AutoCompletionManager(tableElementArticle, sqlTableArticle.getField("NOM"), this.table, this.table.getRowValuesTableModel(),
ITextWithCompletion.MODE_CONTAINS, true, true) {
ITextWithCompletion.MODE_CONTAINS, true, true, new ValidStateChecker()) {
@Override
protected Object getValueFrom(SQLRow row, String field) {
Object res = tarifCompletion(row, field);
/trunk/OpenConcerto/src/org/openconcerto/erp/core/common/component/SocieteCommonSQLElement.java
215,7 → 215,7
 
c.gridx++;
c.weightx = 1;
DeviseField fieldCapital = new DeviseField();
JTextField fieldCapital = new JTextField();
this.add(fieldCapital, c);
this.addView(fieldCapital, "CAPITAL");
 
/trunk/OpenConcerto/src/org/openconcerto/erp/panel/ListeFastPrintFrame.java
19,17 → 19,15
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.utils.ExceptionHandler;
 
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.concurrent.ExecutionException;
 
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
81,15 → 79,21
c.gridx++;
this.panel.add(new JLabel(" exemplaire(s) sur " + bSheet.getPrinter()));
 
c.gridy++;
c.gridx = 0;
final JPanel panelOp = new JPanel(new FlowLayout(FlowLayout.LEFT));
panelOp.setBorder(BorderFactory.createEmptyBorder());
final JPanel panelOp = new JPanel(new GridBagLayout());
 
GridBagConstraints cOp = new DefaultGridBagConstraints();
cOp.weightx = 0;
cOp.gridx = GridBagConstraints.RELATIVE;
cOp.insets = new Insets(2, 0, 3, 2);
panelOp.add(new JLabel("Opération en cours : "), cOp);
cOp.weightx = 1;
cOp.insets = DefaultGridBagConstraints.getDefaultInsets();
panelOp.add(this.operation, cOp);
 
c.gridwidth = GridBagConstraints.REMAINDER;
c.weightx = 0;
 
panelOp.add(new JLabel("Opération en cours : "));
panelOp.add(this.operation);
c.gridx = 0;
c.gridy++;
this.panel.add(panelOp, c);
 
c.gridy++;
/trunk/OpenConcerto/src/org/openconcerto/erp/panel/UserExitPanel.java
21,6 → 21,7
import org.openconcerto.ui.DefaultGridBagConstraints;
import org.openconcerto.ui.UserExit;
 
import java.awt.Frame;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
34,6 → 35,7
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Set;
 
import javax.swing.JButton;
import javax.swing.JDialog;
233,6 → 235,18
// 5 s d'attente
Thread.sleep(5 * 1000);
System.err.println("Warning: Forcing exit");
Frame[] l = Frame.getFrames();
for (int i = 0; i < l.length; i++) {
Frame f = l[i];
System.err.println(f.getName() + " " + f + " Displayable: " + f.isDisplayable() + " Valid: " + f.isValid() + " Active: " + f.isActive());
}
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for (Thread thread : threadSet) {
if (!thread.isDaemon()) {
System.err.println(thread.getName() + " " + thread.getId() + " not daemon");
}
}
 
Thread t = new Thread(new Runnable() {
@Override
public void run() {
/trunk/OpenConcerto/src/org/openconcerto/erp/panel/ChargementCreationSocietePanel.java
139,7 → 139,7
 
try {
String insert = "INSERT INTO \"" + baseNewSociete.getName() + "\".\"COMPTE_PCE\" (\"NUMERO\", \"NOM\", \"INFOS\") VALUES (?, ?, ?)";
PreparedStatement stmt = baseNewSociete.getBase().getDataSource().getConnection().prepareStatement(insert);
PreparedStatement stmt = baseNewSociete.getBase().getDataSource().getNewConnection().prepareStatement(insert);
 
for (int i = 0; i < tmpCpt.size(); i++) {
Map tmp = (HashMap) tmpCpt.get(i);
/trunk/OpenConcerto/src/org/openconcerto/erp/panel/compta/ExportRelationExpertPanel.java
142,9 → 142,9
SQLTable tableJrnl = base.getTable("JOURNAL");
 
sel.addSelect(tableEcriture.getField("NOM"));
sel.addJoin("LEFT", "ECRITURE.ID_COMPTE_PCE");
sel.addJoin("LEFT", "ECRITURE.ID_MOUVEMENT");
sel.addJoin("LEFT", "ECRITURE.ID_JOURNAL");
sel.addJoin("LEFT", tableEcriture.getField("ID_COMPTE_PCE"));
sel.addJoin("LEFT", tableEcriture.getField("ID_MOUVEMENT"));
sel.addJoin("LEFT", tableEcriture.getField("ID_JOURNAL"));
sel.addSelect(tableMouvement.getField("NUMERO"));
sel.addSelect(tableCompte.getField("NUMERO"));
sel.addSelect(tableEcriture.getField("DATE"));
/trunk/OpenConcerto/src/org/openconcerto/erp/model/MouseSheetXmlListeListener.java
31,15 → 31,13
 
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
 
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.SwingUtilities;
 
public class MouseSheetXmlListeListener {
278,6 → 276,7
 
return evt.getSelectedRow() != null && (evt.getTotalRowCount() >= 1) && (createAbstractSheet(evt.getSelectedRow().asRow()).getGeneratedFile().exists());
}
 
};
l.add(action);
 
334,7 → 333,9
public void actionPerformed(ActionEvent ev) {
createAbstractSheet(IListe.get(ev).getSelectedRow()).fastPrintDocument();
}
 
}, this.printHeader) {
 
@Override
public boolean enabledFor(IListeEvent evt) {
return evt.getSelectedRow() != null && evt.getTotalRowCount() >= 1 && createAbstractSheet(evt.getSelectedRow().asRow()).getGeneratedFile().exists();
404,9 → 405,39
public boolean enabledFor(List<SQLRowAccessor> selection) {
return selection != null && selection.size() == 1;
}
 
});
}
 
return l;
}
 
/**
* Action sur le double clic
*
* @return
*/
public RowAction getDefaultRowAction() {
return new RowAction(new AbstractAction(this.generateString) {
public void actionPerformed(ActionEvent ev) {
final AbstractSheetXml sheet = createAbstractSheet(IListe.get(ev).getSelectedRow().asRow());
try {
sheet.getOrCreateDocumentFile();
sheet.showPrintAndExportAsynchronous(true, false, true);
} catch (Exception exn) {
ExceptionHandler.handle("Une erreur est survenue lors de la création du document.", exn);
}
}
}, false, false) {
@Override
public boolean enabledFor(List<SQLRowAccessor> selection) {
return selection != null && selection.size() == 1;
}
 
@Override
public Action getDefaultAction(final IListeEvent evt) {
return this.getAction();
}
};
}
}
/trunk/OpenConcerto/src/org/openconcerto/erp/utils/correct/CorrectMouvement.java
61,7 → 61,7
final String selFixableUnbalanced = "( " + selUnbalanced.asString() + "\nEXCEPT\n" + selUnfixable.asString() + " )";
 
final UpdateBuilder updateUnbalanced = new UpdateBuilder(ecritureT);
updateUnbalanced.addTable(selFixableUnbalanced, SQLBase.quoteIdentifier("semiArchivedMvt"));
updateUnbalanced.addRawTable(selFixableUnbalanced, SQLBase.quoteIdentifier("semiArchivedMvt"));
updateUnbalanced.setWhere(Where.quote("%i = %f", new SQLName("semiArchivedMvt", "ID_MOUVEMENT"), ecritureMvtFF));
updateUnbalanced.set(ecritureT.getArchiveField().getName(), "0");
 
94,8 → 94,8
selIdentifiableNonUsed.setHaving(Where.createRaw("count(*) = 1"));
 
final UpdateBuilder update = new UpdateBuilder(saisieKmElemT);
update.addTable(saisieKmT.getSQLName().quote(), null);
update.addTable("( " + selIdentifiableNonUsed.asString() + " )", "e");
update.addTable(saisieKmT);
update.addRawTable("( " + selIdentifiableNonUsed.asString() + " )", "e");
 
final Where joinSaisieKmW = new Where(saisieKmElemT.getField("ID_SAISIE_KM"), "=", saisieKmT.getKey());
Where joinEcritureW = null;
/trunk/OpenConcerto/src/org/openconcerto/erp/utils/ActionDB.java
71,8 → 71,8
 
try {
log(l, "Création du schéma");
if (!sysRoot.getRootsToMap().contains(baseDefault)) {
sysRoot.getRootsToMap().add(baseDefault);
if (!sysRoot.getChildrenNames().contains(baseDefault)) {
sysRoot.addRootToMap(baseDefault);
sysRoot.refetch(Collections.singleton(baseDefault));
}
final DBRoot baseSQLDefault = sysRoot.getRoot(baseDefault);
86,7 → 86,7
ds.execute(sql.get(0));
// create tables (without constraints)
ds.execute(sql.get(1));
sysRoot.getRootsToMap().add(newBase);
sysRoot.addRootToMap(newBase);
// TODO find a more functional way
final boolean origVal = Boolean.getBoolean(SQLSchema.NOAUTO_CREATE_METADATA);
if (!origVal)
167,7 → 167,7
String baseName = tableSociete.getRow(base).getString("DATABASE_NAME");
String baseDefaultName = tableSociete.getRow(baseDefault).getString("DATABASE_NAME");
 
instance.getBase().getDBSystemRoot().getRootsToMap().clear();
instance.getBase().getDBSystemRoot().mapAllRoots();
try {
Set<String> s = new HashSet<String>();
s.add(baseName);
459,14 → 459,15
public static void correct(SQLBase base) {
Set<String> tableNames = base.getTableNames();
for (String tableName : tableNames) {
 
if (base.getTable(tableName).contains("ORDRE")) {
final SQLTable t = base.getTable(tableName);
final SQLField orderF = t.getOrderField();
if (orderF != null) {
SQLSelect select = new SQLSelect(base);
select.addSelect("ORDRE");
select.addSelect(orderF);
List l = base.getDataSource().execute(select.asString());
if (l == null || l.size() == 0) {
SQLRowValues rowVals = new SQLRowValues(base.getTable(tableName));
rowVals.put("ORDRE", 0);
SQLRowValues rowVals = new SQLRowValues(t);
rowVals.put(orderF.getName(), 0);
try {
rowVals.commit();
} catch (SQLException e) {
504,7 → 505,7
 
String baseName = tableSociete.getRow(base).getString("DATABASE_NAME");
 
instance.getBase().getDBSystemRoot().getRootsToMap().clear();
instance.getBase().getDBSystemRoot().mapAllRoots();
try {
Set<String> s = new HashSet<String>();
s.add(baseName);
/trunk/OpenConcerto/src/org/openconcerto/ftp/updater/UpdateManager.java
24,6 → 24,7
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.Properties;
120,7 → 121,13
if (!logged) {
throw new IllegalStateException("Identifiants refusés");
}
bReaderRemote = new BufferedReader(new InputStreamReader(ftp.retrieveFileStream(this.file)));
if (this.file == null) {
throw new IllegalStateException("Fichier de version non spécifié");
} else {
System.err.println("UpdateManager downloading '" + this.file + "'");
}
final InputStream retrieveFileStream = ftp.retrieveFileStream(this.file);
bReaderRemote = new BufferedReader(new InputStreamReader(retrieveFileStream));
 
int newVersion = Integer.parseInt(bReaderRemote.readLine());
 
140,7 → 147,7
}
 
// / marche pas: ftp.quit();
 
System.err.println("UpdateManager current version: " + currentVersion + " new version: " + newVersion);
if (newVersion > currentVersion) {
Object[] options = { "Maintenant", "Plus tard" };
int res = JOptionPane.showOptionDialog(null, "Une mise à jour est disponible. Installer la mise à jour:", "Mises à jour automatiques", JOptionPane.DEFAULT_OPTION,
200,6 → 207,10
 
}
tempDir.mkdir();
if (!tempDir.exists()) {
JOptionPane.showMessageDialog(null, "Impossible de créer le dossier Update\nVérifiez les permissions des fichiers ou lancez le logiciel en tant qu'administrateur");
return;
}
File f = new File("Update/.version");
FileOutputStream fOp;
try {
209,7 → 220,8
out.println(toVersion);
out.close();
} catch (FileNotFoundException e1) {
JOptionPane.showMessageDialog(null, "Impossible de créer le .version");
JOptionPane.showMessageDialog(null, "Impossible de créer le .version\nVérifiez les permissions des fichiers ou lancez le logiciel en tant qu'administrateur");
return;
}
final IFtp ftp = new IFtp();
try {
/trunk/OpenConcerto/src/org/openconcerto/map/ui/ITextComboVilleViewer.java
112,7 → 112,7
});
 
final IComboCacheListModel comboCacheListModel = new IComboCacheListModel(this.cache);
comboCacheListModel.initCacheLater(this.text);
this.text.initCache(comboCacheListModel.load());
// Listen on data
final PropertyChangeListener listener = new PropertyChangeListener() {
@Override
/trunk/OpenConcerto/src/org/openconcerto/map/model/villes.txt
176248,3 → 176248,8
692437
6485616
63610
Saint-Maur-des-Fossés
75251
664756
6857877
94100
/trunk/OpenConcerto/src/org/openconcerto/openoffice/StyledNode.java
58,6 → 58,18
// can be null if this node wasn't created from a document (eg new Paragraph())
public abstract D getODDocument();
 
public final StyleDesc<S> getStyleDesc() {
return this.styleClass;
}
 
public final <S2 extends Style> StyleDesc<S2> getStyleDesc(Class<S2> clazz) {
return Style.getStyleDesc(clazz, getODDocument().getVersion());
}
 
public final <S2 extends StyleStyle> StyleStyleDesc<S2> getStyleStyleDesc(Class<S2> clazz) {
return Style.getStyleStyleDesc(clazz, getODDocument().getVersion());
}
 
public final S getStyle() {
// null avoid getting styleName if we haven't any Document
return this.getStyle(null);
/trunk/OpenConcerto/src/org/openconcerto/openoffice/generation/ReportGeneration.java
16,6 → 16,7
import org.openconcerto.openoffice.ODSingleXMLDocument;
import org.openconcerto.openoffice.generation.desc.ReportPart;
import org.openconcerto.openoffice.generation.desc.ReportType;
import org.openconcerto.openoffice.generation.desc.part.CaseReportPart;
import org.openconcerto.openoffice.generation.desc.part.ConditionalPart;
import org.openconcerto.openoffice.generation.desc.part.ForkReportPart;
import org.openconcerto.openoffice.generation.desc.part.GeneratorReportPart;
283,6 → 284,8
add(currentDoc, doc);
}
}
} else if (part instanceof CaseReportPart) {
s.push(Tuple2.create(((CaseReportPart) part).evaluate(this).iterator(), currentDoc));
} else {
add(currentDoc, this.createTaskAndGenerate(((GeneratorReportPart) part)));
}
345,11 → 348,15
private final boolean mustGenerate(ReportPart part) throws OgnlException {
if (part instanceof ConditionalPart) {
final ConditionalPart p = (ConditionalPart) part;
return p.getCondition() == null || ((Boolean) Ognl.getValue(p.getCondition(), getCommonData())).booleanValue();
return p.getCondition() == null || evaluatePredicate(p.getCondition());
} else
return true;
}
 
public final boolean evaluatePredicate(String p) throws OgnlException {
return ((Boolean) Ognl.getValue(p, getCommonData())).booleanValue();
}
 
/**
* Une thread qui pour une liste de générateurs.
*/
/trunk/OpenConcerto/src/org/openconcerto/openoffice/generation/desc/part/CaseReportPart.java
New file
0,0 → 1,154
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.openoffice.generation.desc.part;
 
import org.openconcerto.openoffice.generation.ReportGeneration;
import org.openconcerto.openoffice.generation.desc.ReportPart;
import org.openconcerto.openoffice.generation.desc.ReportType;
import org.openconcerto.utils.CollectionUtils;
import org.openconcerto.xml.JDOMUtils;
 
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;
 
import ognl.OgnlException;
 
import org.jdom.Element;
 
/**
* A report part allowing to execute a block of parts or another.
*
* <ul>
* <li>
* Each condition is an expression that returns a boolean result. If the condition's result is true,
* the value of the CASE expression is the result that follows the condition, and the remainder of
* the CASE expression is not processed. If the condition's result is not true, any subsequent WHEN
* clauses are examined in the same manner. If no WHEN condition yields true, the value of the CASE
* expression is the result of the ELSE clause. If the ELSE clause is omitted and no condition is
* true, an exception is thrown.
*
* <pre>
* {@code
* <case>
* <when condition=""></when>
* <else></else>
* </case>
* </pre>
*
* }</li>
* <li>
* There is a "simple" form of CASE expression that is a variant of the general form above:
*
* <pre>
* {@code
* <case expr="">
* <when value=""></when>
* <when value=""></when>
* <else></else>
* </case>
* }
* </pre>
*
* The first expression is computed, then compared to each of the value expressions in the WHEN
* clauses until one is found that is equal to it. If no match is found, the result of the ELSE
* clause is returned. This is similar to the switch statement in C. Multiple values can be
* specified with an or element :
*
* <pre>
* {@code
* <case expr="">
* <when>
* <or value="" />
* <or value="" />
* <then>
* </then>
* </when>
* <when value=""></when>
* <else></else>
* </case>
* }
* </pre>
*
* </li>
* </ul>
*
* @author Sylvain
*/
public final class CaseReportPart extends ReportPart implements ConditionalPart {
 
static private final String getRequiredAttr(final Element elem, final String attrName) {
final String attrVal = elem.getAttributeValue(attrName);
if (attrVal == null)
throw new IllegalStateException("Missing " + attrName + " for " + JDOMUtils.output(elem));
return attrVal;
}
 
private final LinkedHashMap<String, List<ReportPart>> parts;
private final List<ReportPart> elseParts;
private final String expr;
 
public CaseReportPart(ReportType type, Element elem) {
super(type, elem);
this.parts = new LinkedHashMap<String, List<ReportPart>>();
this.expr = this.elem.getAttributeValue("expr");
final List children = this.elem.getChildren();
final int childrenCount = children.size();
for (int i = 0; i < childrenCount; i++) {
final Element child = (Element) children.get(i);
if (child.getName().equals("when")) {
final String cond;
if (this.expr == null) {
cond = getRequiredAttr(child, "condition");
} else {
final Element thenElem = child.getChild("then");
final List orElems;
if (thenElem == null) {
orElems = Collections.singletonList(child);
} else {
orElems = child.getChildren("or");
}
final int orSize = orElems.size();
if (orSize == 0)
throw new IllegalStateException("missing value to compare to expr");
final List<String> orConditions = new ArrayList<String>(orSize);
for (int j = 0; j < orSize; j++) {
orConditions.add("( " + this.expr + " ) == " + getRequiredAttr((Element) orElems.get(j), "value"));
}
cond = CollectionUtils.join(orConditions, " or ");
}
this.parts.put(cond, type.createParts(child));
} else if (i == childrenCount - 1 && child.getName().equals("else")) {
if (child.getAttributeValue("condition") != null || child.getAttributeValue("value") != null)
throw new IllegalStateException("Else shouldn't have condition or value : " + JDOMUtils.output(child));
this.parts.put(null, type.createParts(child));
} else {
throw new IllegalStateException("Unknown element at " + i + " : " + child);
}
}
this.elseParts = this.parts.remove(null);
}
 
public final List<ReportPart> evaluate(final ReportGeneration<?> rg) throws OgnlException {
for (final Entry<String, List<ReportPart>> e : this.parts.entrySet()) {
if (rg.evaluatePredicate(e.getKey()))
return e.getValue();
}
if (this.elseParts == null)
throw new IllegalStateException("No predicate succeeded");
return this.elseParts;
}
}
/trunk/OpenConcerto/src/org/openconcerto/openoffice/generation/desc/ReportType.java
92,7 → 92,7
return this.rg;
}
 
synchronized List<ReportPart> createParts(Element elem) {
public synchronized List<ReportPart> createParts(Element elem) {
// approximation
final List<ReportPart> res = new ArrayList<ReportPart>(elem.getContentSize());
 
/trunk/OpenConcerto/src/org/openconcerto/openoffice/generation/desc/ReportPart.java
15,6 → 15,7
 
import org.openconcerto.openoffice.generation.desc.part.ForkReportPart;
import org.openconcerto.openoffice.generation.desc.part.GeneratorReportPart;
import org.openconcerto.openoffice.generation.desc.part.CaseReportPart;
import org.openconcerto.openoffice.generation.desc.part.InsertReportPart;
import org.openconcerto.openoffice.generation.desc.part.SubReportPart;
 
39,6 → 40,7
tagsName.add("fork");
tagsName.add("insert");
tagsName.add("sub");
tagsName.add("case");
}
 
static public final boolean isPart(Element elem) {
57,6 → 59,8
res.add(new InsertReportPart(parent, child));
} else if (tagName.equals("sub")) {
res.add(new SubReportPart(parent, child, parent.createParts(child)));
} else if (tagName.equals("case")) {
res.add(new CaseReportPart(parent, child));
} else {
throw new IllegalArgumentException(child + " is not a part");
}
/trunk/OpenConcerto/src/org/openconcerto/openoffice/StyleStyleDesc.java
74,7 → 74,17
}
 
public final S findDefaultStyle(final ODPackage pkg) {
final Element styleElem = pkg.getDefaultStyle(this);
return this.getDefaultStyle(pkg, false);
}
public final S getDefaultStyle(final ODPackage pkg, final boolean create) {
final Element styleElem = pkg.getDefaultStyle(this, create);
return styleElem == null ? null : this.create(pkg, styleElem);
}
 
public final Element createDefaultElement() {
final Element res = new Element(StyleStyleDesc.ELEMENT_DEFAULT_NAME, getElementNS());
this.initStyle(res);
return res;
}
}
/trunk/OpenConcerto/src/org/openconcerto/openoffice/spreadsheet/ColumnStyle.java
15,6 → 15,7
 
import org.openconcerto.openoffice.LengthUnit;
import org.openconcerto.openoffice.ODPackage;
import org.openconcerto.openoffice.Style;
import org.openconcerto.openoffice.StyleProperties;
import org.openconcerto.openoffice.StyleStyle;
import org.openconcerto.openoffice.StyleStyleDesc;
27,7 → 28,7
public class ColumnStyle extends StyleStyle {
 
// from section 18.728 in v1.2-part1
public static final StyleStyleDesc<ColumnStyle> DESC = new StyleStyleDesc<ColumnStyle>(ColumnStyle.class, XMLVersion.OD, "table-column", "co", "table") {
private static final StyleStyleDesc<ColumnStyle> DESC = new StyleStyleDesc<ColumnStyle>(ColumnStyle.class, XMLVersion.OD, "table-column", "co", "table") {
@Override
public ColumnStyle create(ODPackage pkg, Element e) {
return new ColumnStyle(pkg, e);
34,6 → 35,10
}
};
 
static public void registerDesc() {
Style.registerAllVersions(DESC);
}
 
private StyleTableColumnProperties colProps;
 
public ColumnStyle(final ODPackage pkg, Element tableColElem) {
/trunk/OpenConcerto/src/org/openconcerto/openoffice/spreadsheet/Table.java
49,9 → 49,17
public class Table<D extends ODDocument> extends TableCalcNode<TableStyle, D> {
 
static Element createEmpty(XMLVersion ns) {
// from the relaxNG : a table must have at least one cell
return createEmpty(ns, 1, 1);
}
 
static Element createEmpty(final XMLVersion ns, final int colCount, final int rowCount) {
// from the relaxNG
if (colCount < 1 || rowCount < 1)
throw new IllegalArgumentException("a table must have at least one cell");
final Element col = Column.createEmpty(ns, null);
final Element row = Row.createEmpty(ns).addContent(Cell.createEmpty(ns));
Axis.COLUMN.setRepeated(col, colCount);
final Element row = Row.createEmpty(ns).addContent(Cell.createEmpty(ns, colCount));
Axis.ROW.setRepeated(row, rowCount);
return new Element("table", ns.getTABLE()).addContent(col).addContent(row);
}
 
816,7 → 824,7
}
 
private final ColumnStyle createDefaultColStyle() {
final ColumnStyle colStyle = ColumnStyle.DESC.createAutoStyle(this.getODDocument().getPackage(), "defaultCol");
final ColumnStyle colStyle = this.getStyleDesc(ColumnStyle.class).createAutoStyle(this.getODDocument().getPackage(), "defaultCol");
colStyle.setWidth(20.0f);
return colStyle;
}
/trunk/OpenConcerto/src/org/openconcerto/openoffice/spreadsheet/RowStyle.java
15,6 → 15,7
 
import org.openconcerto.openoffice.LengthUnit;
import org.openconcerto.openoffice.ODPackage;
import org.openconcerto.openoffice.Style;
import org.openconcerto.openoffice.StyleProperties;
import org.openconcerto.openoffice.StyleStyle;
import org.openconcerto.openoffice.StyleStyleDesc;
27,7 → 28,7
public class RowStyle extends StyleStyle {
 
// from section 18.728 in v1.2-part1
public static final StyleStyleDesc<RowStyle> DESC = new StyleStyleDesc<RowStyle>(RowStyle.class, XMLVersion.OD, "table-row", "ro", "table") {
private static final StyleStyleDesc<RowStyle> DESC = new StyleStyleDesc<RowStyle>(RowStyle.class, XMLVersion.OD, "table-row", "ro", "table") {
@Override
public RowStyle create(ODPackage pkg, Element e) {
return new RowStyle(pkg, e);
34,6 → 35,10
}
};
 
static public void registerDesc() {
Style.registerAllVersions(DESC);
}
 
private StyleTableRowProperties rowProps;
 
public RowStyle(final ODPackage pkg, Element tableColElem) {
/trunk/OpenConcerto/src/org/openconcerto/openoffice/spreadsheet/MutableCell.java
24,7 → 24,6
import org.openconcerto.openoffice.style.data.BooleanStyle;
import org.openconcerto.openoffice.style.data.DataStyle;
import org.openconcerto.openoffice.style.data.DateStyle;
import org.openconcerto.utils.ExceptionUtils;
import org.openconcerto.utils.FileUtils;
import org.openconcerto.utils.Tuple3;
 
40,6 → 39,7
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.logging.Level;
 
import javax.xml.datatype.DatatypeConstants;
import javax.xml.datatype.Duration;
256,7 → 256,7
}
} catch (UnsupportedOperationException e) {
if (lenient)
Log.get().warning(ExceptionUtils.getStackTrace(e));
Log.get().log(Level.WARNING, "Couldn't format", e);
else
throw e;
}
/trunk/OpenConcerto/src/org/openconcerto/openoffice/spreadsheet/Column.java
25,9 → 25,6
final Element res = new Element("table-column", ns.getTABLE());
if (style != null)
res.setAttribute("style-name", style.getName(), ns.getTABLE());
// need default-cell-style-name otherwise some cells types are ignored
// (eg date treated as a float)
res.setAttribute("default-cell-style-name", "Default", ns.getTABLE());
return res;
}
 
/trunk/OpenConcerto/src/org/openconcerto/openoffice/spreadsheet/CellStyle.java
52,7 → 52,7
private static final Pattern cellContentBetweenPatrn = Pattern.compile("cell-content-is(?:-not)?-between\\(" + valuePatrn + ", *" + valuePatrn + "\\)");
 
// from section 18.728 in v1.2-part1
public static final StyleStyleDesc<CellStyle> DESC = new StyleStyleDesc<CellStyle>(CellStyle.class, XMLVersion.OD, "table-cell", "ce", "table", Arrays.asList("table:body",
private static final StyleStyleDesc<CellStyle> DESC = new StyleStyleDesc<CellStyle>(CellStyle.class, XMLVersion.OD, "table-cell", "ce", "table", Arrays.asList("table:body",
"table:covered-table-cell", "table:even-rows", "table:first-column", "table:first-row", "table:last-column", "table:last-row", "table:odd-columns", "table:odd-rows", "table:table-cell")) {
 
{
102,6 → 102,10
}
};
 
static public void registerDesc() {
Style.registerAllVersions(DESC);
}
 
private static final Pattern conditionPatrn = Pattern.compile("value\\(\\) *(" + RelationalOperator.OR_PATTERN + ") *(true|false|" + numberPatrn.pattern() + ")");
 
// from style:condition :
258,6 → 262,20
public final Integer getDecimalPlaces() {
return parseInteger(this.getAttributeValue("decimal-places", this.getElement().getNamespace("style")));
}
 
public final boolean isWrapping() {
final String val = this.getAttributeValue("wrap-option", this.getElement().getNamespace("fo"));
if (val == null || val.equals("no-wrap"))
return false;
else if (val.equals("wrap"))
return true;
else
throw new IllegalStateException("Unknown value : " + val);
}
 
public final void setWrapping(final boolean b) {
this.getElement().setAttribute("wrap-option", b ? "wrap" : "no-wrap", this.getElement().getNamespace("fo"));
}
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/openoffice/spreadsheet/SpreadSheet.java
60,15 → 60,26
return fd.hasODDocument() ? fd.getSpreadSheet() : new SpreadSheet(fd);
}
 
public static SpreadSheet createEmpty(TableModel t) throws IOException {
public static SpreadSheet createEmpty(TableModel t) {
return createEmpty(t, XMLFormatVersion.getDefault());
}
 
public static SpreadSheet createEmpty(TableModel t, XMLFormatVersion ns) throws IOException {
public static SpreadSheet createEmpty(TableModel t, XMLFormatVersion ns) {
final SpreadSheet spreadSheet = create(ns, 1, 1, 1);
spreadSheet.getFirstSheet().merge(t, 0, 0, true);
return spreadSheet;
}
 
public static SpreadSheet create(final int sheetCount, final int colCount, final int rowCount) {
return create(XMLFormatVersion.getDefault(), sheetCount, colCount, rowCount);
}
 
public static SpreadSheet create(final XMLFormatVersion ns, final int sheetCount, final int colCount, final int rowCount) {
final ContentTypeVersioned ct = ContentType.SPREADSHEET.getVersioned(ns.getXMLVersion());
final SpreadSheet spreadSheet = ct.createPackage(ns).getSpreadSheet();
spreadSheet.getBody().addContent(Sheet.createEmpty(ns.getXMLVersion()));
spreadSheet.getSheet(0).merge(t, 0, 0, true);
for (int i = 0; i < sheetCount; i++) {
spreadSheet.getBody().addContent(Sheet.createEmpty(ns.getXMLVersion(), colCount, rowCount));
}
return spreadSheet;
}
 
202,6 → 213,10
return this.getTables().size();
}
 
public final Sheet getFirstSheet() {
return this.getSheet(0);
}
 
public Sheet getSheet(int i) {
return this.getSheet(getTables().get(i));
}
/trunk/OpenConcerto/src/org/openconcerto/openoffice/spreadsheet/TableStyle.java
15,6 → 15,7
 
import org.openconcerto.openoffice.LengthUnit;
import org.openconcerto.openoffice.ODPackage;
import org.openconcerto.openoffice.Style;
import org.openconcerto.openoffice.StyleStyle;
import org.openconcerto.openoffice.StyleStyleDesc;
import org.openconcerto.openoffice.XMLVersion;
29,7 → 30,7
 
static public final LengthUnit DEFAULT_UNIT = LengthUnit.MM;
// from section 18.728 in v1.2-part1
public static final StyleStyleDesc<TableStyle> DESC = new StyleStyleDesc<TableStyle>(TableStyle.class, XMLVersion.OD, "table", "ta", "table", Arrays.asList("table:background", "table:table")) {
private static final StyleStyleDesc<TableStyle> DESC = new StyleStyleDesc<TableStyle>(TableStyle.class, XMLVersion.OD, "table", "ta", "table", Arrays.asList("table:background", "table:table")) {
@Override
public TableStyle create(ODPackage pkg, Element e) {
return new TableStyle(pkg, e);
36,6 → 37,10
}
};
 
static public void registerDesc() {
Style.registerAllVersions(DESC);
}
 
private StyleTableProperties tableProps;
 
public TableStyle(final ODPackage pkg, Element tableColElem) {
/trunk/OpenConcerto/src/org/openconcerto/openoffice/GraphicStyle.java
31,7 → 31,7
public class GraphicStyle extends StyleStyle {
 
// from section 18.222 in v1.2-part1
public static final StyleStyleDesc<GraphicStyle> DESC = new StyleStyleDesc<GraphicStyle>(GraphicStyle.class, XMLVersion.OD, "graphic", "fr", "draw", Arrays.asList("dr3d:cube", "dr3d:extrude",
private static final StyleStyleDesc<GraphicStyle> DESC = new StyleStyleDesc<GraphicStyle>(GraphicStyle.class, XMLVersion.OD, "graphic", "fr", "draw", Arrays.asList("dr3d:cube", "dr3d:extrude",
"dr3d:rotate", "dr3d:scene", "dr3d:sphere", "draw:caption", "draw:circle", "draw:connector", "draw:control", "draw:custom-shape", "draw:ellipse", "draw:frame", "draw:g", "draw:line",
"draw:measure", "draw:page-thumbnail", "draw:path", "draw:polygon", "draw:polyline", "draw:rect", "draw:regular-polygon", "office:annotation")) {
 
42,7 → 42,7
};
 
// from §2.6 Frames and §5.3 Drawing shapes in OpenOffice.org XML File Format 1.0
public static final StyleStyleDesc<GraphicStyle> DESC_OO = new StyleStyleDesc<GraphicStyle>(GraphicStyle.class, XMLVersion.OOo, "graphics", "fr", "draw", Arrays.asList("draw:text-box",
private static final StyleStyleDesc<GraphicStyle> DESC_OO = new StyleStyleDesc<GraphicStyle>(GraphicStyle.class, XMLVersion.OOo, "graphics", "fr", "draw", Arrays.asList("draw:text-box",
"draw:image", "draw:caption", "draw:circle", "draw:connector", "draw:control", "draw:ellipse", "draw:line", "draw:measure", "draw:page-thumbnail", "draw:path", "draw:polygon",
"draw:polyline", "draw:rect")) {
 
52,6 → 52,11
}
};
 
static public void registerDesc() {
Style.register(DESC);
Style.register(DESC_OO);
}
 
private StyleTextProperties textProps;
private StyleParagraphProperties pProps;
private StyleGraphicProperties graphProps;
/trunk/OpenConcerto/src/org/openconcerto/openoffice/StyleDesc.java
268,7 → 268,7
public final S createAutoStyle(final ODPackage pkg, final String baseName) {
final ODXMLDocument xml = pkg.getContent();
final Namespace style = xml.getVersion().getSTYLE();
final Element elem = new Element(getElementName(), style);
final Element elem = new Element(getElementName(), getElementNS());
this.initStyle(elem);
elem.setAttribute("name", xml.findUnusedName(this, baseName), style);
xml.addAutoStyle(elem);
/trunk/OpenConcerto/src/org/openconcerto/openoffice/Style.java
70,24 → 70,21
// loads StyleStyle which needs PStyle.DESC)
private static void loadDescs() {
if (!descsLoaded) {
registerAllVersions(CellStyle.DESC);
registerAllVersions(RowStyle.DESC);
registerAllVersions(ColumnStyle.DESC);
registerAllVersions(TableStyle.DESC);
registerAllVersions(TextStyle.DESC);
registerAllVersions(ParagraphStyle.DESC);
for (final StyleDesc<?> d : DataStyle.DATA_STYLES_DESCS)
registerAllVersions(d);
register(GraphicStyle.DESC);
register(GraphicStyle.DESC_OO);
register(PageLayoutStyle.DESC);
register(PageLayoutStyle.DESC_OO);
CellStyle.registerDesc();
RowStyle.registerDesc();
ColumnStyle.registerDesc();
TableStyle.registerDesc();
TextStyle.registerDesc();
ParagraphStyle.registerDesc();
DataStyle.registerDesc();
GraphicStyle.registerDesc();
PageLayoutStyle.registerDesc();
descsLoaded = true;
}
}
 
// until now styles have remained constant through versions
private static void registerAllVersions(StyleDesc<? extends Style> desc) {
// until now a majority of styles have remained constant through versions
public static void registerAllVersions(StyleDesc<? extends Style> desc) {
for (final XMLVersion v : XMLVersion.values()) {
if (v == desc.getVersion())
register(desc);
126,9 → 123,9
*
* <pre>
* [ element qualified name, attribute qualified name ] -> StyleDesc ; e.g. :
* [ "text:p", "text:style-name" ] -> {@link ParagraphStyle#DESC}
* [ "text:h", "text:style-name" ] -> {@link ParagraphStyle#DESC}
* [ "text:span", "text:style-name" ] -> {@link TextStyle#DESC}
* [ "text:p", "text:style-name" ] -> <code>StyleStyleDesc&lt;ParagraphStyle&gt;</code>
* [ "text:h", "text:style-name" ] -> <code>StyleStyleDesc&lt;ParagraphStyle&gt;</code>
* [ "text:span", "text:style-name" ] -> <code>StyleStyleDesc&lt;TextStyle&gt;</code>
* </pre>
*
* @param version the version.
/trunk/OpenConcerto/src/org/openconcerto/openoffice/text/Paragraph.java
14,6 → 14,7
package org.openconcerto.openoffice.text;
 
import org.openconcerto.openoffice.ODDocument;
import org.openconcerto.openoffice.Style;
import org.openconcerto.openoffice.XMLVersion;
 
import java.util.HashSet;
123,7 → 124,7
if (this.getStyleName() != null && getStyle(doc.getPackage(), doc.getContentDocument()) == null)
throw new IllegalArgumentException("unknown style " + getStyleName() + " in " + doc);
for (final String styleName : this.getUsedTextStyles()) {
if (doc.getPackage().getStyle(TextStyle.DESC, styleName) == null) {
if (doc.getPackage().getStyle(Style.getStyleDesc(TextStyle.class, doc.getVersion()), styleName) == null) {
throw new IllegalArgumentException(this + " is using a text:span with an undefined style : " + styleName);
}
}
/trunk/OpenConcerto/src/org/openconcerto/openoffice/text/TextStyle.java
28,7 → 28,7
 
public class TextStyle extends StyleStyle {
 
public static final StyleStyleDesc<TextStyle> DESC = new StyleStyleDesc<TextStyle>(TextStyle.class, XMLVersion.OD, "text", "T") {
private static final StyleStyleDesc<TextStyle> DESC = new StyleStyleDesc<TextStyle>(TextStyle.class, XMLVersion.OD, "text", "T") {
 
{
// from section 19.876 in v1.2-part1-cd04
41,6 → 41,10
}
};
 
static public void registerDesc() {
Style.registerAllVersions(DESC);
}
 
private StyleTextProperties textProps;
 
public TextStyle(final ODPackage pkg, Element tableColElem) {
/trunk/OpenConcerto/src/org/openconcerto/openoffice/text/ParagraphStyle.java
15,6 → 15,7
 
import static java.util.Arrays.asList;
import org.openconcerto.openoffice.ODPackage;
import org.openconcerto.openoffice.Style;
import org.openconcerto.openoffice.StyleProperties;
import org.openconcerto.openoffice.StyleStyle;
import org.openconcerto.openoffice.StyleStyleDesc;
24,7 → 25,7
 
public class ParagraphStyle extends TextStyle {
 
public static final StyleStyleDesc<ParagraphStyle> DESC = new StyleStyleDesc<ParagraphStyle>(ParagraphStyle.class, XMLVersion.OD, "paragraph", "P") {
private static final StyleStyleDesc<ParagraphStyle> DESC = new StyleStyleDesc<ParagraphStyle>(ParagraphStyle.class, XMLVersion.OD, "paragraph", "P") {
 
{
// from section 18.876 in v1.2-part1
41,8 → 42,7
this.getRefElementsMap().putAll("form:text-style-name", asList("form:column"));
// 19.690 (apparently not implemented by OpenOffice 3.2 - or any older version)
this.getRefElementsMap()
.putAll(
"table:paragraph-style-name",
.putAll("table:paragraph-style-name",
asList("table:body", "table:even-columns", "table:even-rows", "table:first-column", "table:first-row", "table:last-column", "table:last-row", "table:odd-columns",
"table:odd-rows"));
}
53,6 → 53,10
}
};
 
static public void registerDesc() {
Style.registerAllVersions(DESC);
}
 
private StyleParagraphProperties pProps;
 
public ParagraphStyle(final ODPackage pkg, Element tableColElem) {
/trunk/OpenConcerto/src/org/openconcerto/openoffice/ODPackage.java
17,7 → 17,6
import static org.openconcerto.openoffice.ODPackage.RootElement.META;
import static org.openconcerto.openoffice.ODPackage.RootElement.STYLES;
import org.openconcerto.openoffice.spreadsheet.SpreadSheet;
import org.openconcerto.openoffice.text.ParagraphStyle;
import org.openconcerto.openoffice.text.TextDocument;
import org.openconcerto.utils.CollectionMap;
import org.openconcerto.utils.CopyUtils;
701,7 → 700,7
/**
* Find the passed automatic or common style referenced from the content.
*
* @param desc the family, eg {@link ParagraphStyle#DESC}.
* @param desc the family, eg <code>StyleStyleDesc&lt;ParagraphStyle&gt;</code>.
* @param name the name, eg "P1".
* @return the corresponding XML element.
*/
714,7 → 713,7
* there can exist automatic styles with the same name in both "content.xml" and "styles.xml".
*
* @param referent the document referencing the style.
* @param desc the family, eg {@link ParagraphStyle#DESC}.
* @param desc the family, eg <code>StyleStyleDesc&lt;ParagraphStyle&gt;</code>.
* @param name the name, eg "P1".
* @return the corresponding XML element.
* @see ODXMLDocument#getStyle(StyleDesc, String)
739,9 → 738,9
return res;
}
 
public final Element getDefaultStyle(final StyleStyleDesc<?> desc) {
public final Element getDefaultStyle(final StyleStyleDesc<?> desc, final boolean create) {
// from 16.4 of OpenDocument-v1.2-cs01-part1, default-style only usable in office:styles
return getStyles().getDefaultStyle(desc);
return getStyles().getDefaultStyle(desc, create);
}
 
/**
/trunk/OpenConcerto/src/org/openconcerto/openoffice/style/data/DateStyle.java
42,7 → 42,7
private static final Calendar JAPANESE_CAL = Calendar.getInstance(new Locale("ja", "JP", "JP"));
private static final Calendar GREGORIAN_CAL = new GregorianCalendar();
 
public static final DataStyleDesc<DateStyle> DESC = new DataStyleDesc<DateStyle>(DateStyle.class, XMLVersion.OD, "date-style", "N") {
static final DataStyleDesc<DateStyle> DESC = new DataStyleDesc<DateStyle>(DateStyle.class, XMLVersion.OD, "date-style", "N") {
@Override
public DateStyle create(ODPackage pkg, Element e) {
return new DateStyle(pkg, e);
/trunk/OpenConcerto/src/org/openconcerto/openoffice/style/data/TimeStyle.java
36,7 → 36,7
// from section 16.27.18 in v1.2-cs01-part1
public class TimeStyle extends DataStyle {
 
public static final DataStyleDesc<TimeStyle> DESC = new DataStyleDesc<TimeStyle>(TimeStyle.class, XMLVersion.OD, "time-style", "N") {
static final DataStyleDesc<TimeStyle> DESC = new DataStyleDesc<TimeStyle>(TimeStyle.class, XMLVersion.OD, "time-style", "N") {
@Override
public TimeStyle create(ODPackage pkg, Element e) {
return new TimeStyle(pkg, e);
/trunk/OpenConcerto/src/org/openconcerto/openoffice/style/data/BooleanStyle.java
30,7 → 30,7
// from section 16.27.23 in v1.2-cs01-part1
public class BooleanStyle extends DataStyle {
 
public static final DataStyleDesc<BooleanStyle> DESC = new DataStyleDesc<BooleanStyle>(BooleanStyle.class, XMLVersion.OD, "boolean-style", "N") {
static final DataStyleDesc<BooleanStyle> DESC = new DataStyleDesc<BooleanStyle>(BooleanStyle.class, XMLVersion.OD, "boolean-style", "N") {
@Override
public BooleanStyle create(ODPackage pkg, Element e) {
return new BooleanStyle(pkg, e);
/trunk/OpenConcerto/src/org/openconcerto/openoffice/style/data/PercentStyle.java
26,7 → 26,7
// from section 16.27.9 in v1.2-cs01-part1
public class PercentStyle extends DataStyle {
 
public static final DataStyleDesc<PercentStyle> DESC = new DataStyleDesc<PercentStyle>(PercentStyle.class, XMLVersion.OD, "percentage-style", "N") {
static final DataStyleDesc<PercentStyle> DESC = new DataStyleDesc<PercentStyle>(PercentStyle.class, XMLVersion.OD, "percentage-style", "N") {
@Override
public PercentStyle create(ODPackage pkg, Element e) {
return new PercentStyle(pkg, e);
/trunk/OpenConcerto/src/org/openconcerto/openoffice/style/data/TextStyle.java
26,7 → 26,7
// from section 16.27.25 in v1.2-cs01-part1
public class TextStyle extends DataStyle {
 
public static final DataStyleDesc<TextStyle> DESC = new DataStyleDesc<TextStyle>(TextStyle.class, XMLVersion.OD, "text-style", "N") {
static final DataStyleDesc<TextStyle> DESC = new DataStyleDesc<TextStyle>(TextStyle.class, XMLVersion.OD, "text-style", "N") {
@Override
public TextStyle create(ODPackage pkg, Element e) {
return new TextStyle(pkg, e);
/trunk/OpenConcerto/src/org/openconcerto/openoffice/style/data/NumberStyle.java
32,7 → 32,7
// from section 16.27.2 in v1.2-cs01-part1
public class NumberStyle extends DataStyle {
 
public static final DataStyleDesc<NumberStyle> DESC = new DataStyleDesc<NumberStyle>(NumberStyle.class, XMLVersion.OD, "number-style", "N") {
static final DataStyleDesc<NumberStyle> DESC = new DataStyleDesc<NumberStyle>(NumberStyle.class, XMLVersion.OD, "number-style", "N") {
@Override
public NumberStyle create(ODPackage pkg, Element e) {
return new NumberStyle(pkg, e);
/trunk/OpenConcerto/src/org/openconcerto/openoffice/style/data/DataStyle.java
62,7 → 62,7
formatSB.append('\'');
}
 
public static final DataStyleDesc<?>[] DATA_STYLES_DESCS = new DataStyleDesc<?>[] { NumberStyle.DESC, PercentStyle.DESC, TextStyle.DESC, CurrencyStyle.DESC, DateStyle.DESC, TimeStyle.DESC,
private static final DataStyleDesc<?>[] DATA_STYLES_DESCS = new DataStyleDesc<?>[] { NumberStyle.DESC, PercentStyle.DESC, TextStyle.DESC, CurrencyStyle.DESC, DateStyle.DESC, TimeStyle.DESC,
BooleanStyle.DESC };
 
public static abstract class DataStyleDesc<S extends DataStyle> extends StyleDesc<S> {
80,6 → 80,15
}
}
 
static public void registerDesc() {
for (final StyleDesc<?> d : DATA_STYLES_DESCS)
Style.registerAllVersions(d);
}
 
static public <S extends DataStyle> DataStyleDesc<S> getDesc(final Class<S> clazz, final XMLVersion version) {
return (DataStyleDesc<S>) Style.getStyleDesc(clazz, version);
}
 
private final ODValueType type;
private StyleTextProperties textProps;
 
/trunk/OpenConcerto/src/org/openconcerto/openoffice/style/data/CurrencyStyle.java
27,7 → 27,7
// from section 16.27.7 in v1.2-cs01-part1
public class CurrencyStyle extends DataStyle {
 
public static final DataStyleDesc<CurrencyStyle> DESC = new DataStyleDesc<CurrencyStyle>(CurrencyStyle.class, XMLVersion.OD, "currency-style", "N") {
static final DataStyleDesc<CurrencyStyle> DESC = new DataStyleDesc<CurrencyStyle>(CurrencyStyle.class, XMLVersion.OD, "currency-style", "N") {
@Override
public CurrencyStyle create(ODPackage pkg, Element e) {
return new CurrencyStyle(pkg, e);
/trunk/OpenConcerto/src/org/openconcerto/openoffice/style/PageLayoutStyle.java
28,7 → 28,7
// from section 16.5 in v1.2-part1-cd04
public class PageLayoutStyle extends Style {
 
public static final StyleDesc<PageLayoutStyle> DESC = new StyleDesc<PageLayoutStyle>(PageLayoutStyle.class, XMLVersion.OD, "page-layout", "pm") {
private static final StyleDesc<PageLayoutStyle> DESC = new StyleDesc<PageLayoutStyle>(PageLayoutStyle.class, XMLVersion.OD, "page-layout", "pm") {
{
// from section 19.506 in v1.2-part1-cd04
this.getRefElementsMap().putAll("style:page-layout-name", asList("presentation:notes", "style:handout-master", "style:master-page"));
39,7 → 39,7
return new PageLayoutStyle(pkg, e);
}
};
public static final StyleDesc<PageLayoutStyle> DESC_OO = new StyleDesc<PageLayoutStyle>(PageLayoutStyle.class, XMLVersion.OOo, "page-master", "pm") {
private static final StyleDesc<PageLayoutStyle> DESC_OO = new StyleDesc<PageLayoutStyle>(PageLayoutStyle.class, XMLVersion.OOo, "page-master", "pm") {
{
// from DTD
this.getRefElementsMap().putAll("style:page-master-name", asList("presentation:notes", "style:handout-master", "style:master-page"));
51,6 → 51,11
}
};
 
static public void registerDesc() {
Style.register(DESC);
Style.register(DESC_OO);
}
 
private PageLayoutProperties props;
 
public PageLayoutStyle(final ODPackage pkg, Element tableColElem) {
/trunk/OpenConcerto/src/org/openconcerto/openoffice/ODXMLDocument.java
17,7 → 17,6
package org.openconcerto.openoffice;
 
import org.openconcerto.openoffice.ODPackage.RootElement;
import org.openconcerto.openoffice.spreadsheet.ColumnStyle;
import org.openconcerto.utils.cc.IFactory;
import org.openconcerto.xml.JDOMUtils;
import org.openconcerto.xml.Validator;
247,11 → 246,18
return null;
}
 
public final Element getDefaultStyle(final StyleStyleDesc<?> styleDesc) {
final Element root = this.getDocument().getRootElement();
final Namespace office = getVersion().getOFFICE();
return this.findStyleChild(root.getChild("styles", office), styleDesc.getElementNS(), StyleStyleDesc.ELEMENT_DEFAULT_NAME, styleDesc.getFamily(), null);
public final Element getDefaultStyle(final StyleStyleDesc<?> styleDesc, final boolean create) {
final Element stylesElem = this.getChild("styles", create);
final Element res = this.findStyleChild(stylesElem, styleDesc.getElementNS(), StyleStyleDesc.ELEMENT_DEFAULT_NAME, styleDesc.getFamily(), null);
if (res != null || !create) {
return res;
} else {
final Element created = styleDesc.createDefaultElement();
// OK to add at the end, the relaxNG for office:styles is 'interleave'
stylesElem.addContent(created);
return created;
}
}
 
private final Element findStyleChild(final Element styles, final Namespace elemNS, final String elemName, final String family, final String name) {
if (styles == null)
272,9 → 278,10
/**
* Find an unused style name in this document.
*
* @param desc the description of the style, eg {@link ColumnStyle#DESC}.
* @param baseName the base name, eg "myColStyle".
* @return an unused name, eg "myColStyle12".
* @param desc the description of the style.
* @param baseName the base name, e.g. "myColStyle".
* @return an unused name, e.g. "myColStyle12".
* @see Style#getStyleDesc(Class, XMLVersion)
*/
public final String findUnusedName(final StyleDesc<?> desc, final String baseName) {
for (int i = 0; i < 1000; i++) {
/trunk/OpenConcerto/src/org/openconcerto/ui/group/Group.java
117,38 → 117,47
 
public void dumpTwoColumn() {
final StringBuilder b = new StringBuilder();
System.out.println("==== Group "+this.getId()+" ====");
dumpTwoColumn(b, 0, LayoutHints.DEFAULT_GROUP_HINTS, 0, 1);
System.out.println(b.toString());
}
 
public int dumpTwoColumn(StringBuilder builder, int x, LayoutHints localHint, int localOrder, int level) {
public void dumpTwoColumn(StringBuilder builder, int x, LayoutHints localHint, int localOrder, int level) {
if (localHint.isSeparated()) {
x = 0;
builder.append(" -------\n");
}
if (isEmpty()) {
if (localHint.largeWidth() && x>0) {
builder.append("\n");
x = 0;
}
if (isEmpty()) {
// print a leaf
builder.append(" (" + x + ")");
builder.append(localOrder + " " + this.id + "[" + localHint + "]");
 
if ((x % 2) == 1) {
if (localHint.largeWidth()) {
x += 2;
} else {
x++;
}
 
if (x > 1) {
builder.append("\n");
x = 0;
}
}
} else {
// Subgroup
sortSubGroup();
for (Tuple3<Group, LayoutHints, Integer> tuple : list) {
final Group subGroup = tuple.get0();
final Integer subGroupOrder = (Integer) tuple.get2();
x = subGroup.dumpTwoColumn(builder, x, tuple.get1(), subGroupOrder, level + 1);
subGroup.dumpTwoColumn(builder, x, tuple.get1(), subGroupOrder, level + 1);
}
if (isEmpty()) {
x++;
}
if (!localHint.isSeparated() && list.size() != 0 && localHint.maximizeWidth()) {
x = 0;
builder.append("\n");
 
 
}
return x;
}
 
public int getSize() {
return this.list.size();
/trunk/OpenConcerto/src/org/openconcerto/ui/group/LayoutHints.java
15,42 → 15,37
 
public class LayoutHints {
 
private boolean maximizeWidth;
private boolean maximizeHeight;
private boolean largeWidth;
private boolean largeHeight;
 
private boolean showLabel;
private boolean separated;
private boolean fill;
public static final LayoutHints DEFAULT_FIELD_HINTS = new LayoutHints(false, false, true, false);
public static final LayoutHints DEFAULT_LARGE_FIELD_HINTS = new LayoutHints(true, false, true, false);
public static final LayoutHints DEFAULT_LIST_HINTS = new LayoutHints(true, true, false, false, true);
public static final LayoutHints DEFAULT_GROUP_HINTS = new LayoutHints(false, false, false, false);
public static final LayoutHints DEFAULT_LARGE_GROUP_HINTS = new LayoutHints(true, false, false, false);
public static final LayoutHints DEFAULT_SEPARATED_GROUP_HINTS = new LayoutHints(true, false, false, true);
private boolean fillWidth;
private boolean fillHeight;
public static final LayoutHints DEFAULT_FIELD_HINTS = new LayoutHints(false, false, true, false, false, false);
public static final LayoutHints DEFAULT_LARGE_FIELD_HINTS = new LayoutHints(false, false, true, false, true, false);
public static final LayoutHints DEFAULT_VERY_LARGE_FIELD_HINTS = new LayoutHints(true, false, true, false, false, false);
public static final LayoutHints DEFAULT_LIST_HINTS = new LayoutHints(true, true, false, true, true, true);
public static final LayoutHints DEFAULT_GROUP_HINTS = new LayoutHints(true, false, false, false, true, true);
public static final LayoutHints DEFAULT_SEPARATED_GROUP_HINTS = new LayoutHints(true, false, true, true, true, true);
 
public LayoutHints(boolean maximizeWidth, boolean maximizeHeight, boolean showLabel, boolean separated) {
this.maximizeWidth = maximizeWidth;
this.maximizeHeight = maximizeHeight;
public LayoutHints(boolean largeWidth, boolean largeHeight, boolean showLabel, boolean separated, boolean fillWidth, boolean fillHeight) {
this.largeWidth = largeWidth;
this.largeHeight = largeHeight;
this.showLabel = showLabel;
this.separated = separated;
this.fill = false;
this.fillWidth = fillWidth;
this.fillHeight = fillHeight;
}
 
public LayoutHints(boolean maximizeWidth, boolean maximizeHeight, boolean showLabel, boolean separated, boolean fill) {
this.maximizeWidth = maximizeWidth;
this.maximizeHeight = maximizeHeight;
this.showLabel = showLabel;
this.separated = separated;
this.fill = fill;
public boolean largeWidth() {
return largeWidth;
}
 
public boolean maximizeWidth() {
return maximizeWidth;
public boolean largeHeight() {
return largeHeight;
}
 
public boolean maximizeHeight() {
return maximizeHeight;
}
 
public boolean showLabel() {
return showLabel;
}
59,21 → 54,25
return separated;
}
 
public boolean fill() {
return fill;
public boolean fillWidth() {
return fillWidth;
}
 
public boolean fillHeight() {
return fillHeight;
}
 
@Override
public String toString() {
String r = "";
if (maximizeHeight && maximizeWidth) {
r += "MaxW&H";
if (largeHeight && largeWidth) {
r += "LargeW&H";
} else {
if (maximizeHeight) {
r += "MaxH";
if (largeHeight) {
r += "LargeH";
}
if (maximizeWidth) {
r += "MaxW";
if (largeWidth) {
r += "LargeW";
}
}
if (showLabel && separated) {
86,9 → 85,16
}
 
}
if (fill) {
r += " Fill";
if (fillHeight && fillWidth) {
r += " FillW&H";
} else {
if (fillHeight) {
r += " FillH";
}
if (fillWidth) {
r += " FillW";
}
}
return r;
}
}
/trunk/OpenConcerto/src/org/openconcerto/ui/EnhancedTable.java
166,72 → 166,19
}
 
public void tableChanged(TableModelEvent e) {
// System.out.println("EnhancedTable.tableChanged()");
 
if (e == null || e.getFirstRow() == TableModelEvent.HEADER_ROW) {
// The whole thing changed
clearSelection();
 
if (getAutoCreateColumnsFromModel())
if (getAutoCreateColumnsFromModel()) {
createDefaultColumnsFromModel();
 
resizeAndRepaint();
 
return;
}
 
if (e.getType() == TableModelEvent.INSERT) {
} else if (e.getType() == TableModelEvent.INSERT) {
tableRowsInserted(e);
repaint();// En plus
return;
}
 
if (e.getType() == TableModelEvent.DELETE) {
} else if (e.getType() == TableModelEvent.DELETE) {
tableRowsDeleted(e);
repaint();// En plus
return;
}
 
int modelColumn = e.getColumn();
int start = e.getFirstRow();
int end = e.getLastRow();
 
if (start == TableModelEvent.HEADER_ROW) {
start = 0;
end = Integer.MAX_VALUE;
}
 
// int rowHeight = getRowHeight() + rowMargin;
Rectangle dirtyRegion;
if (modelColumn == TableModelEvent.ALL_COLUMNS) {
// 1 or more rows changed
// dirtyRegion = new Rectangle(0, start * rowHeight,
dirtyRegion = new Rectangle(0, getCellRect(start, 0, false).y,
 
getColumnModel().getTotalColumnWidth(), 0);
} else {
// A cell or column of cells has changed.
// Unlike the rest of the methods in the JTable, the TableModelEvent
// uses the co-ordinate system of the model instead of the view.
// This is the only place in the JTable where this "reverse mapping"
// is used.
int column = convertColumnIndexToView(modelColumn);
dirtyRegion = getCellRect(start, column, false);
}
 
// Now adjust the height of the dirty region according to the value of "end".
// Check for Integer.MAX_VALUE as this will cause an overflow.
if (end != Integer.MAX_VALUE) {
// dirtyRegion.height = (end-start+1)*rowHeight;
dirtyRegion.height = getCellRect(end + 1, 0, false).y - dirtyRegion.y;
repaint(dirtyRegion.x, dirtyRegion.y, dirtyRegion.width, dirtyRegion.height);
}
// In fact, if the end is Integer.MAX_VALUE we need to revalidate anyway
// because the scrollbar may need repainting.
else {
resizeAndRepaint();
}
}
 
private void tableRowsInserted(TableModelEvent e) {
// System.out.println("EnhancedTable.tableRowsInserted()");
/trunk/OpenConcerto/src/org/openconcerto/ui/ReloadPanel.java
51,6 → 51,7
* @author G. Maillard
*/
public class ReloadPanel extends JComponent {
private static final BasicStroke ROUND_STROKE = new BasicStroke(5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
protected int pos;
private int mode;
public static final int MODE_ROTATE = 0;
58,11 → 59,12
public static final int MODE_EMPTY = 2;
private final Runnable r;
private boolean stop = false;
private boolean sleep = false;
private boolean sleep;
private Color[] cols = new Color[] { new Color(0, 0, 0, 10), new Color(120, 0, 0, 30), new Color(120, 0, 0, 50), new Color(120, 0, 0, 80), new Color(120, 0, 0, 150), new Color(120, 0, 0, 200) };
 
public ReloadPanel() {
this.mode = MODE_EMPTY;
this.sleep = true;
setPreferredSize(new Dimension(16, 16));
setMinimumSize(new Dimension(16, 16));
setMaximumSize(new Dimension(16, 16));
73,7 → 75,6
if (sleep) {
try {
synchronized (this) {
setMode(MODE_EMPTY);
repaint();
this.wait();
}
130,7 → 131,7
}
 
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
g2.setStroke(ROUND_STROKE);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
 
// Circles drawing
169,6 → 170,7
*/
public void setMode(int mode) {
this.mode = mode;
setSleeping(mode == MODE_EMPTY);
repaint();
}
 
177,12 → 179,16
*
* @param bool
*/
public void setSleeping(boolean bool) {
private void setSleeping(boolean bool) {
if (sleep != bool) {
this.sleep = bool;
repaint();
if (!sleep) {
synchronized (this.r) {
this.r.notify();
}
}
}
}
 
}
/trunk/OpenConcerto/src/org/openconcerto/ui/TextAreaTableCellEditor.java
66,9 → 66,7
SwingUtilities.invokeLater(new Runnable() {
public void run() {
 
fireEditingStopped();
 
if (t.getCellEditor().stopCellEditing()) {
if (column >= 0 && column < t.getColumnCount()) {
t.setColumnSelectionInterval(column, column);
t.setRowSelectionInterval(row, row);
78,6 → 76,7
}
}
}
}
});
} else {
if (e.getKeyCode() == KeyEvent.VK_SPACE && e.getModifiers() == KeyEvent.SHIFT_MASK) {
/trunk/OpenConcerto/src/org/openconcerto/ui/state/JTableStateManager.java
44,6 → 44,11
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
 
/**
* Save the width and order of columns in a JTable.
*
* @author Sylvain
*/
public class JTableStateManager extends ListenerXMLStateManager<JTable, AncestorListener> {
 
private static final String VERSION = "20100810";
/trunk/OpenConcerto/src/org/openconcerto/ui/preferences/AbstractProps.java
23,7 → 23,6
import java.io.IOException;
import java.util.Properties;
 
import javax.swing.JFrame;
import javax.swing.JOptionPane;
 
public abstract class AbstractProps {
139,7 → 138,7
bufferedInputStream = new BufferedInputStream(fileInputStream);
this.props.load(bufferedInputStream);
} catch (IOException e) {
JOptionPane.showMessageDialog(new JFrame(), "Impossible de lire le fichier de configuration:\n" + file.getAbsolutePath());
JOptionPane.showMessageDialog(null, "Impossible de lire le fichier de configuration:\n" + file.getAbsolutePath());
e.printStackTrace();
} finally {
if (bufferedInputStream != null) {
161,7 → 160,7
bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
this.props.store(bufferedOutputStream, "");
} catch (IOException e) {
JOptionPane.showMessageDialog(new JFrame(), "Impossible d'enregistrer le fichier de configuration:\n" + file.getAbsolutePath());
JOptionPane.showMessageDialog(null, "Impossible d'enregistrer le fichier de configuration:\n" + file.getAbsolutePath());
e.printStackTrace();
} finally {
if (bufferedOutputStream != null) {
/trunk/OpenConcerto/src/org/openconcerto/ui/component/IComboCacheListModel.java
74,6 → 74,11
};
}
 
public final IComboCacheListModel load() {
this.load(null, true);
return this;
}
 
public final void load(final Runnable r, final boolean readCache) {
if (this.cache.isValid()) {
new SwingWorker2<List<String>, Object>() {
/trunk/OpenConcerto/src/org/openconcerto/ui/component/ITextCombo.java
159,8 → 159,14
return this.locked == LOCKED;
}
 
public void initCache(ITextComboCache cache) {
if (this.cache != null)
public final boolean hasCache() {
return this.cache != null;
}
 
public final void initCache(ITextComboCache cache) {
if (cache == null)
throw new NullPointerException("null cache");
if (this.hasCache())
throw new IllegalStateException("cache already set " + this.cache);
 
this.cache = cache;
/trunk/OpenConcerto/src/org/openconcerto/ui/component/combo/ISearchableCombo.java
439,7 → 439,7
return this.cache;
}
 
public void initCache(final IListModel<T> acache) {
public final void initCache(final IListModel<T> acache) {
if (acache == null)
throw new NullPointerException("null cache");
if (this.getCache() != null)
674,7 → 674,9
private final void setValue(final T val, final ValidState valid) {
log("entering " + this.getClass().getSimpleName() + ".setValue '" + val + "' valid: " + valid);
final ISearchableComboItem<T> comboItem;
if (val == null)
// as in docChanged(), "" means empty (otherwise an ISearchableComboItem will be created and
// it won't be contained in the list)
if (val == null || "".equals(val))
comboItem = null;
else if (this.itemsByOriginalItem.containsKey(val)) {
comboItem = this.itemsByOriginalItem.get(val);
/trunk/OpenConcerto/src/org/openconcerto/ui/component/TextPrompt.java
New file
0,0 → 1,210
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
*
* The contents of this file are subject to the terms of the GNU General Public License Version 3
* only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
* copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each file.
*/
package org.openconcerto.ui.component;
 
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
 
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
 
/**
* The TextPrompt class will display a prompt over top of a text component when the Document of the
* text field is empty. The Show property is used to determine the visibility of the prompt.
*
* The Font and foreground Color of the prompt will default to those properties of the parent text
* component. You are free to change the properties after class construction.
*
* @see <a href="http://tips4java.wordpress.com/2009/11/29/text-prompt/">Java Tips Weblog</a>
*/
public class TextPrompt extends JLabel implements FocusListener, DocumentListener {
public enum Show {
ALWAYS, FOCUS_GAINED, FOCUS_LOST;
}
 
private final JTextComponent component;
private final Document document;
 
private Show show;
private boolean showPromptOnce;
private int focusLost;
 
public TextPrompt(final String text, final JTextComponent component) {
this(text, component, Show.ALWAYS);
}
 
public TextPrompt(final String text, final JTextComponent component, final Show show) {
this.component = component;
setShow(show);
this.document = component.getDocument();
 
setText(text);
setFont(component.getFont());
setForeground(component.getForeground());
setBorder(new EmptyBorder(component.getInsets()));
setHorizontalAlignment(SwingConstants.LEADING);
changeAlpha(160);
 
component.addFocusListener(this);
this.document.addDocumentListener(this);
 
component.setLayout(new BorderLayout());
component.add(this);
checkForPrompt();
}
 
/**
* Convenience method to change the alpha value of the current foreground Color to the specifice
* value.
*
* @param alpha value in the range of 0 - 1.0.
*/
public void changeAlpha(final float alpha) {
changeAlpha((int) (alpha * 255));
}
 
/**
* Convenience method to change the alpha value of the current foreground Color to the specifice
* value.
*
* @param alpha value in the range of 0 - 255.
*/
public void changeAlpha(int alpha) {
alpha = alpha > 255 ? 255 : alpha < 0 ? 0 : alpha;
 
final Color foreground = getForeground();
final int red = foreground.getRed();
final int green = foreground.getGreen();
final int blue = foreground.getBlue();
 
final Color withAlpha = new Color(red, green, blue, alpha);
super.setForeground(withAlpha);
}
 
/**
* Convenience method to change the style of the current Font. The style values are found in the
* Font class. Common values might be: Font.BOLD, Font.ITALIC and Font.BOLD + Font.ITALIC.
*
* @param style value representing the the new style of the Font.
*/
public void changeStyle(final int style) {
setFont(getFont().deriveFont(style));
}
 
/**
* Get the Show property
*
* @return the Show property.
*/
public Show getShow() {
return this.show;
}
 
/**
* Set the prompt Show property to control when the promt is shown. Valid values are:
*
* Show.AWLAYS (default) - always show the prompt Show.Focus_GAINED - show the prompt when the
* component gains focus (and hide the prompt when focus is lost) Show.Focus_LOST - show the
* prompt when the component loses focus (and hide the prompt when focus is gained)
*
* @param show a valid Show enum
*/
public void setShow(final Show show) {
this.show = show;
}
 
/**
* Get the showPromptOnce property
*
* @return the showPromptOnce property.
*/
public boolean getShowPromptOnce() {
return this.showPromptOnce;
}
 
/**
* Show the prompt once. Once the component has gained/lost focus once, the prompt will not be
* shown again.
*
* @param showPromptOnce when true the prompt will only be shown once, otherwise it will be
* shown repeatedly.
*/
public void setShowPromptOnce(final boolean showPromptOnce) {
this.showPromptOnce = showPromptOnce;
}
 
/**
* Check whether the prompt should be visible or not. The visibility will change on updates to
* the Document and on focus changes.
*/
private void checkForPrompt() {
// Text has been entered, remove the prompt
if (this.document.getLength() > 0) {
setVisible(false);
return;
}
 
// Prompt has already been shown once, remove it
if (this.showPromptOnce && this.focusLost > 0) {
setVisible(false);
return;
}
 
// Check the Show property and component focus to determine if the
// prompt should be displayed.
final boolean vis;
if (this.component.hasFocus()) {
vis = this.show == Show.ALWAYS || this.show == Show.FOCUS_GAINED;
} else {
vis = this.show == Show.ALWAYS || this.show == Show.FOCUS_LOST;
}
setVisible(vis);
}
 
// Implement FocusListener
 
@Override
public void focusGained(final FocusEvent e) {
checkForPrompt();
}
 
@Override
public void focusLost(final FocusEvent e) {
this.focusLost++;
checkForPrompt();
}
 
// Implement DocumentListener
 
@Override
public void insertUpdate(final DocumentEvent e) {
checkForPrompt();
}
 
@Override
public void removeUpdate(final DocumentEvent e) {
checkForPrompt();
}
 
@Override
public void changedUpdate(final DocumentEvent e) {
}
}
/trunk/OpenConcerto/src/org/openconcerto/sql/sqlobject/SQLSearchableTextCombo.java
52,9 → 52,10
super(mode, rows, columns, textArea);
}
 
@Override
public void init(SQLRowItemView v) {
// after uiInit since our superclass add listeners to our UI
this.initCacheLater(new ISQLListModel(v.getField()));
if (this.getCache() == null)
this.initCache(new ISQLListModel(v.getField()).load());
}
 
/**
/trunk/OpenConcerto/src/org/openconcerto/sql/sqlobject/ISQLElementWithCodeSelector.java
146,7 → 146,7
this.mainField = this.mainCombo.getFields().iterator().next();
 
if (expandWithShowAs) {
this.optCombo = new ComboSQLRequest(this.element.getComboRequest());
this.optCombo = this.element.getComboRequest(true);
} else {
List<String> optFields = new ArrayList<String>();
optFields.add(this.optField.getName());
/trunk/OpenConcerto/src/org/openconcerto/sql/sqlobject/SQLTextCombo.java
52,11 → 52,14
super(mode);
}
 
@Override
public void init(SQLRowItemView v) {
if (!this.hasCache()) {
final ITextComboCacheSQL cache = new ITextComboCacheSQL(v.getField());
if (cache.isValid())
this.initCache(cache);
}
}
 
static public class ITextComboCacheSQL implements ITextComboCache {
 
/trunk/OpenConcerto/src/org/openconcerto/sql/sqlobject/JUniqueTextField.java
339,7 → 339,13
 
@Override
public ValidState getValidState() {
 
boolean endWithSpace = getText().endsWith(" ");
if (endWithSpace) {
return ValidState.createCached(!endWithSpace, "la valeur ne peut pas se terminer par un espace!");
}
return ValidState.createCached(this.isValidated, "Le numéro existe déjà");
 
}
 
private synchronized void runValidationThread() {
/trunk/OpenConcerto/src/org/openconcerto/sql/Configuration.java
148,11 → 148,18
*/
public abstract void destroy();
 
/**
* An executor that should be used for background SQL requests. It can be used to limit the
* concurrent number of database connections (as establishing a connection is expensive and the
* server might have restrictions).
*
* @return a SQL executor.
*/
public Executor getNonInteractiveSQLExecutor() {
if (nonInteractiveSQLExecutor == null) {
nonInteractiveSQLExecutor = createNonInteractiveSQLExecutor();
if (this.nonInteractiveSQLExecutor == null) {
this.nonInteractiveSQLExecutor = createNonInteractiveSQLExecutor();
}
return nonInteractiveSQLExecutor;
return this.nonInteractiveSQLExecutor;
}
 
protected Executor createNonInteractiveSQLExecutor() {
/trunk/OpenConcerto/src/org/openconcerto/sql/request/ComboSQLRequest.java
37,6 → 37,8
import org.openconcerto.utils.cc.ITransformer;
 
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
 
// final: use setSelectTransf()
67,8 → 69,8
setDefaultFieldSeparator(" | ");
}
 
// pour la combo
private final List<SQLField> comboFields;
// immutable
private List<SQLField> comboFields;
private final TransfFieldExpander exp;
 
private String fieldSeparator = SEP_FIELD;
96,22 → 98,16
return Configuration.getInstance().getDirectory().getElement(foreignTable).getComboRequest().getFields();
}
});
this.comboFields = new ArrayList<SQLField>();
 
for (final String fName : l) {
this.addItemToCombo(fName);
this.setFields(l);
}
}
 
// public since this class is final (otherwise should be protected)
public ComboSQLRequest(ComboSQLRequest c) {
this(c, new ArrayList<SQLField>(c.comboFields));
}
 
public ComboSQLRequest(ComboSQLRequest c, List<SQLField> fields) {
super(c);
this.exp = new TransfFieldExpander(c.exp);
this.comboFields = fields;
this.comboFields = c.comboFields;
this.order = c.order == null ? null : new ArrayList<Path>(c.order);
 
this.fieldSeparator = c.fieldSeparator;
this.undefLabel = c.undefLabel;
this.keepRows = c.keepRows;
118,10 → 114,26
this.customizeItem = c.customizeItem;
}
 
private void addItemToCombo(String field) {
this.comboFields.add(this.getPrimaryTable().getField(field));
public final void setFields(Collection<String> fields) {
final List<SQLField> l = new ArrayList<SQLField>();
for (final String fName : fields) {
l.add(this.getPrimaryTable().getField(fName));
}
setSQLFieldsUnsafe(l);
}
 
public final void setSQLFields(Collection<SQLField> fields) {
for (final SQLField f : fields)
if (f.getTable() != getPrimaryTable())
throw new IllegalArgumentException("Not in " + getPrimaryTable() + " : " + f);
setSQLFieldsUnsafe(new ArrayList<SQLField>(fields));
}
 
private void setSQLFieldsUnsafe(List<SQLField> fields) {
this.comboFields = Collections.unmodifiableList(fields);
this.clearGraph();
}
 
/**
* Set the label of the undefined row. If <code>null</code> (the default) then the undefined
* will not be fetched, otherwise it will and its label will be <code>undefLabel</code>.
157,8 → 169,8
}
 
public final List<IComboSelectionItem> getComboItems(final boolean readCache) {
if (this.comboFields.isEmpty())
throw new IllegalStateException("La liste des items listitems est vide!! Ils faut utiliser addComboItem...");
if (this.getFields().isEmpty())
throw new IllegalStateException("Empty fields");
 
// freeze the fetcher otherwise it will change with the filter
// and that will cause the cache to fail
217,6 → 229,7
*/
public final void setOrder(List<Path> l) {
this.order = l;
this.clearGraph();
}
 
private final IComboSelectionItem createItem(final SQLRowValues rs) {
/trunk/OpenConcerto/src/org/openconcerto/sql/request/UpdateBuilder.java
15,7 → 15,10
 
import static java.util.Collections.unmodifiableList;
import static java.util.Collections.unmodifiableMap;
import org.openconcerto.sql.model.SQLBase;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.TableRef;
import org.openconcerto.sql.model.Where;
 
import java.util.ArrayList;
67,14 → 70,28
this.where = where;
}
 
public final void addTable(final TableRef t) {
this.tables.add(t.getSQL());
}
 
/**
* Add table to this UPDATE.
*
* @param sel the select to add.
* @param alias the alias, cannot be <code>null</code>, e.g. <code>t</code>.
*/
public final void addTable(final SQLSelect sel, final String alias) {
this.addRawTable("( " + sel.asString() + " )", SQLBase.quoteIdentifier(alias));
}
 
/**
* Add table to this UPDATE.
*
* @param definition the table to add, ie either a table name or a sub-select.
* @param alias the alias, can be <code>null</code>.
* @param rawAlias the SQL alias, can be <code>null</code>, e.g. <code>"t"</code>.
*/
public final void addTable(final String definition, final String alias) {
this.tables.add(definition + (alias == null ? "" : " " + alias));
public final void addRawTable(final String definition, final String rawAlias) {
this.tables.add(definition + (rawAlias == null ? "" : " " + rawAlias));
}
 
public final String asString() {
/trunk/OpenConcerto/src/org/openconcerto/sql/request/FilteredFillSQLRequest.java
14,7 → 14,6
package org.openconcerto.sql.request;
 
import org.openconcerto.sql.Configuration;
import org.openconcerto.sql.model.AliasedField;
import org.openconcerto.sql.model.SQLFilter;
import org.openconcerto.sql.model.SQLFilterListener;
import org.openconcerto.sql.model.SQLRow;
21,6 → 20,7
import org.openconcerto.sql.model.SQLRowValues;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
import org.openconcerto.sql.model.TableRef;
import org.openconcerto.sql.model.Where;
import org.openconcerto.sql.model.graph.Path;
import org.openconcerto.utils.CollectionUtils;
70,7 → 70,7
public final void setFilterEnabled(boolean b) {
this.filterEnabled = b;
if (this.filterEnabled)
this.getFilter().addListener(this.filterListener);
this.getFilter().addWeakListener(this.filterListener);
else
this.getFilter().rmListener(this.filterListener);
updateFilterWhere();
128,11 → 128,11
throw new IllegalStateException("not 1 table: " + filterRow);
 
final Path path = filterInfo.get1();
final String lastAlias = sel.assurePath(getPrimaryTable().getName(), path);
if (filterTable != sel.getTable(lastAlias))
throw new IllegalStateException("table mismatch: " + filterRow + " is not from " + lastAlias + ": " + sel.getTable(lastAlias));
final TableRef lastAlias = sel.assurePath(getPrimaryTable().getName(), path);
if (filterTable != lastAlias.getTable())
throw new IllegalStateException("table mismatch: " + filterRow + " is not from " + lastAlias + ": " + lastAlias.getTable());
 
sel.andWhere(new Where(new AliasedField(filterTable.getKey(), lastAlias), ids));
sel.andWhere(new Where(lastAlias.getKey(), ids));
}
return super.transformSelect(sel);
}
/trunk/OpenConcerto/src/org/openconcerto/sql/request/ListSQLRequest.java
23,24 → 23,12
import org.openconcerto.utils.cc.ITransformer;
 
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
 
public class ListSQLRequest extends FilteredFillSQLRequest {
 
/**
* Copy the passed request and replace its where.
*
* @param src the object to copy.
* @param newWhere the where of the copy.
* @return a copy of <code>src</code>.
*/
public static final ListSQLRequest copy(ListSQLRequest src, final Where newWhere) {
final ListSQLRequest res = new ListSQLRequest(src);
res.setWhere(newWhere);
return res;
}
 
// les champs à afficher (avant expansion)
private final List<SQLField> listFields;
 
108,7 → 96,7
* @see org.openconcerto.devis.request.BaseSQLRequest#getFields()
*/
public final List<SQLField> getFields() {
return this.listFields;
return Collections.unmodifiableList(this.listFields);
}
 
@Override
/trunk/OpenConcerto/src/org/openconcerto/sql/request/BaseFillSQLRequest.java
105,6 → 105,12
return this.graph;
}
 
// should be called if getFields(), getOrder() or getShowAs() change
protected final void clearGraph() {
this.graph = null;
this.graphToFetch = null;
}
 
/**
* The graph to fetch, should be a superset of {@link #getGraph()}.
*
124,7 → 130,7
protected final SQLRowValuesListFetcher getFetcher(final Where w) {
final String tableName = getPrimaryTable().getName();
// graphToFetch can be modified freely so don't the use the simple constructor
final SQLRowValuesListFetcher fetcher = SQLRowValuesListFetcher.create(getGraphToFetch());
final SQLRowValuesListFetcher fetcher = SQLRowValuesListFetcher.create(getGraphToFetch(), false);
setupForeign(fetcher);
fetcher.setSelTransf(new ITransformer<SQLSelect, SQLSelect>() {
@Override
133,7 → 139,7
if (lockSelect)
sel.addWaitPreviousWriteTXTable(tableName);
for (final Path orderP : getOrder()) {
sel.addOrderSilent(sel.assurePath(getPrimaryTable().getName(), orderP));
sel.addOrder(sel.assurePath(getPrimaryTable().getName(), orderP), false);
}
return sel.andWhere(getWhere()).andWhere(w);
}
/trunk/OpenConcerto/src/org/openconcerto/sql/element/GroupSQLComponent.java
64,10 → 64,17
this.setLayout(new GridBagLayout());
this.group.sort();
final GridBagConstraints c = new DefaultGridBagConstraints();
c.fill = GridBagConstraints.NONE;
layout(this.group, 0, LayoutHints.DEFAULT_GROUP_HINTS, 0, 0, c);
}
 
public int layout(final Group currentGroup, final Integer order, final LayoutHints size, int x, final int level, final GridBagConstraints c) {
public void layout(final Group currentGroup, final Integer order, final LayoutHints size, int x, final int level, final GridBagConstraints c) {
if (size.isSeparated()) {
x = 0;
c.gridx = 0;
c.gridy++;
}
 
if (currentGroup.isEmpty()) {
System.out.print(" (" + x + ")");
final String id = currentGroup.getId();
75,9 → 82,9
c.gridwidth = 1;
if (size.showLabel()) {
c.weightx = 0;
c.weighty = 0;
// Label
if (size.isSeparated()) {
c.gridx = 0;
c.gridwidth = 4;
c.fill = GridBagConstraints.NONE;
} else {
86,6 → 93,7
this.add(getLabel(id), c);
if (size.isSeparated()) {
c.gridy++;
c.gridx = 0;
} else {
c.gridx++;
}
93,20 → 101,30
// Editor
final JComponent editor = getEditor(id);
 
if (size.maximizeWidth() && size.maximizeHeight()) {
if (size.fillWidth() && size.fillHeight()) {
c.fill = GridBagConstraints.BOTH;
} else if (size.maximizeWidth()) {
} else if (size.fillWidth()) {
c.fill = GridBagConstraints.HORIZONTAL;
} else if (size.maximizeHeight()) {
} else if (size.fillHeight()) {
c.fill = GridBagConstraints.VERTICAL;
} else {
c.fill = GridBagConstraints.NONE;
DefaultGridBagConstraints.lockMinimumSize(editor);
}
if (size.fill()) {
if (size.fillHeight()) {
c.weighty = 1;
} else {
c.weighty = 0;
}
if (size.largeWidth()) {
if (size.isSeparated()) {
c.gridwidth = this.columns * 2;
} else {
c.gridwidth = this.columns * 2 - 1;
}
} else {
c.gridwidth = 1;
}
if (c.gridx % 2 == 1) {
c.weightx = 1;
}
116,37 → 134,35
} catch (final Exception e) {
System.err.println(e.getMessage());
}
c.weighty = 0;
 
if (size.largeWidth()) {
if (size.isSeparated()) {
c.gridx += 4;
} else {
c.gridx += 3;
}
} else {
c.gridx++;
if ((x % this.columns) != 0) {
}
 
if (c.gridx >= this.columns * 2) {
c.gridx = 0;
c.gridy++;
}
}
if (size.isSeparated()) {
x = 0;
c.gridx = 0;
c.gridy++;
}
 
} else {
final int stop = currentGroup.getSize();
for (int i = 0; i < stop; i++) {
final Group subGroup = currentGroup.getGroup(i);
final Integer subGroupOrder = currentGroup.getOrder(i);
final LayoutHints subGroupSize = currentGroup.getLayoutHints(i);
x = layout(subGroup, subGroupOrder, subGroupSize, x, level + 1, c);
layout(subGroup, subGroupOrder, subGroupSize, x, level + 1, c);
 
}
 
if (currentGroup.isEmpty()) {
x++;
} else {
if (size.maximizeWidth()) {
c.gridx = 0;
c.gridy++;
}
}
 
return x;
}
 
public JComponent createEditor(final String id) {
/trunk/OpenConcerto/src/org/openconcerto/sql/navigator/SQLBrowserColumn.java
78,6 → 78,7
 
private static final long serialVersionUID = 3340938099896864844L;
 
private static final Color DARK_BLUE = new Color(100, 100, 120);
private static final Icon iconUp = new ImageIcon(LAFUtils.class.getResource("up.png"));
private static final Icon iconDown = new ImageIcon(LAFUtils.class.getResource("down.png"));
private static final Font fontText = new Font("Tahoma", Font.PLAIN, 11);
599,12 → 600,12
 
protected final void focusChanged(boolean gained) {
if (gained) {
this.normalPanel.setBackground(new Color(100, 100, 120));
this.normalPanel.setBackground(DARK_BLUE);
this.title.setForeground(Color.WHITE);
this.list.setSelectionBackground(new Color(100, 100, 120));
this.list.setSelectionBackground(DARK_BLUE);
} else {
this.normalPanel.setBackground(new JPanel().getBackground());
this.title.setForeground(Color.BLACK);
this.normalPanel.setBackground(null);
this.title.setForeground(null);
this.list.setSelectionBackground(Color.LIGHT_GRAY);
}
if (this.getParentBrowser() != null)
/trunk/OpenConcerto/src/org/openconcerto/sql/utils/ReOrderPostgreSQL.java
14,6 → 14,7
package org.openconcerto.sql.utils;
 
import org.openconcerto.sql.model.AliasedField;
import org.openconcerto.sql.model.Order;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLSelect;
import org.openconcerto.sql.model.SQLTable;
50,9 → 51,8
idsToReorder.addSelect(tID, null, "ID");
idsToReorder.setWhere(this.getWhere(tOrder));
// NULLS LAST needs at least 8.3, but 8.2 is sorting nulls high so no need to specify it
final String orderDir = conn.getMetaData().nullsAreSortedHigh() ? " ASC" : " ASC NULLS LAST";
idsToReorder.addRawOrder(tOrder.getFieldRef() + orderDir);
idsToReorder.addRawOrder(tID.getFieldRef() + " ASC");
idsToReorder.addFieldOrder(tOrder, Order.asc(), conn.getMetaData().nullsAreSortedHigh() ? null : Order.nullsLast());
idsToReorder.addFieldOrder(tID, Order.asc());
 
res.add("CREATE TEMP SEQUENCE \"reorderSeq\" MINVALUE 0;");
// REORDER: ID => INDEX
64,8 → 64,8
res.add(this.t.getBase().quote("UPDATE %f SET %n = -%n " + this.getWhere(), this.t, oF, oF) + ";");
 
final UpdateBuilder update = new UpdateBuilder(this.t);
update.addTable("REORDER", "M");
update.addTable("inc", null);
update.addRawTable("REORDER", "M");
update.addRawTable("inc", null);
update.set(oF.getName(), "M.index * inc.val + " + getFirstOrderValue());
res.add(update.asString() + " where M.\"ID\" = " + this.t.getKey().getFieldRef() + ";");
 
/trunk/OpenConcerto/src/org/openconcerto/sql/utils/ReOrderH2.java
14,6 → 14,7
package org.openconcerto.sql.utils;
 
import org.openconcerto.sql.model.AliasedField;
import org.openconcerto.sql.model.Order;
import org.openconcerto.sql.model.SQLField;
import org.openconcerto.sql.model.SQLName;
import org.openconcerto.sql.model.SQLSelect;
50,13 → 51,13
final Where updateNulls = this.isAll() ? new Where(tOrder, "is", (Object) null) : null;
final Where w = new Where(tOrder, "<=", this.getFirstToReorder().negate()).or(updateNulls);
idsToReorder.setWhere(w);
idsToReorder.addRawOrder(tOrder.getFieldRef() + " DESC NULLS LAST");
idsToReorder.addRawOrder(tID.getFieldRef() + " ASC");
idsToReorder.addFieldOrder(tOrder, Order.desc(), Order.nullsLast());
idsToReorder.addFieldOrder(tID, Order.asc());
// REORDER: ID => ORDRE
res.add("DROP TABLE IF EXISTS REORDER ;");
final String idName = this.t.getKey().getName();
res.add("CREATE LOCAL TEMPORARY TABLE REORDER as select M.ID, " + this.getFirstOrderValue() + " +(M.ind - 1) * @inc as ORDRE from (\n" + "SELECT rownum() as ind, " + new SQLName(idName).quote()
+ " as ID from (" + idsToReorder.asString() + ") ) M;");
res.add("CREATE LOCAL TEMPORARY TABLE REORDER as select M.ID, " + this.getFirstOrderValue() + " +(M.ind - 1) * @inc as ORDRE from (\n" + "SELECT rownum() as ind, "
+ new SQLName(idName).quote() + " as ID from (" + idsToReorder.asString() + ") ) M;");
 
res.add(this.t.getBase().quote("UPDATE %f %i SET ( %n ) = (\n" +
// cast since Subquery.getValue() doesn't return an array if there's only 1 column
/trunk/OpenConcerto/src/org/openconcerto/sql/model/SQLSelect.java
13,6 → 13,8
package org.openconcerto.sql.model;
 
import org.openconcerto.sql.model.Order.Direction;
import org.openconcerto.sql.model.Order.Nulls;
import org.openconcerto.sql.model.graph.Path;
import org.openconcerto.utils.CollectionUtils;
import org.openconcerto.utils.cc.ITransformer;
51,7 → 53,6
return SQLBase.quoteStd(pattern, params);
}
 
private final SQLBase base;
// [String], eg : [SITE.ID_SITE, AVG(AGE)]
private final List<String> select;
// [SQLField], eg : [|SITE.ID_SITE|], known fields in this select (addRawSelect)
86,6 → 87,12
// number of rows to return
private Integer limit;
 
/**
* Create a new SQLSelect.
*
* @param base the database of the request.
* @deprecated use {@link #SQLSelect(DBSystemRoot)}
*/
public SQLSelect(SQLBase base) {
this(base, false);
}
96,8 → 103,29
* @param base the database of the request.
* @param plain whether this request should automatically add a where clause for archived and
* undefined.
* @deprecated use {@link #SQLSelect(DBSystemRoot, boolean)}
*/
public SQLSelect(SQLBase base, boolean plain) {
this(base.getDBSystemRoot(), plain);
}
 
public SQLSelect() {
this(false);
}
 
public SQLSelect(boolean plain) {
this((DBSystemRoot) null, plain);
}
 
/**
* Create a new SQLSelect.
*
* @param sysRoot the database of the request, can be <code>null</code> (it will come from
* declared tables).
* @param plain whether this request should automatically add a where clause for archived and
* undefined.
*/
public SQLSelect(DBSystemRoot sysRoot, boolean plain) {
this.select = new ArrayList<String>();
this.selectFields = new ArrayList<SQLField>();
this.where = null;
106,10 → 134,9
this.having = null;
this.order = new ArrayList<String>();
this.from = new FromClause();
this.declaredTables = new AliasedTables();
this.declaredTables = new AliasedTables(sysRoot);
this.joinAliases = new HashSet<String>();
this.joins = new ArrayList<SQLSelectJoin>();
this.base = base;
// false by default cause it slows things down
this.distinct = false;
this.excludeUndefined = new HashMap<SQLTable, Boolean>();
146,7 → 173,6
this.declaredTables = new AliasedTables(orig.declaredTables);
this.joinAliases = new HashSet<String>(orig.joinAliases);
this.joins = new ArrayList<SQLSelectJoin>(orig.joins);
this.base = orig.base;
this.generalExcludeUndefined = orig.generalExcludeUndefined;
this.excludeUndefined = new HashMap<SQLTable, Boolean>(orig.excludeUndefined);
this.archivedPolicy = new HashMap<SQLTable, ArchiveMode>(orig.archivedPolicy);
156,8 → 182,12
this.waitTrxTables = new ArrayList<String>(orig.waitTrxTables);
}
 
public final SQLSystem getSQLSystem() {
return this.declaredTables.getSysRoot().getServer().getSQLSystem();
}
 
public String asString() {
final SQLSystem sys = this.base.getServer().getSQLSystem();
final SQLSystem sys = this.getSQLSystem();
 
final StringBuffer result = new StringBuffer(512);
result.append("SELECT ");
320,23 → 350,47
* @see SQLTable#isOrdered()
*/
public SQLSelect addOrder(String t) {
final SQLTable table = this.getTable(t);
if (!table.isOrdered())
throw new IllegalArgumentException("table is not ordered.");
return this.addFieldOrder(this.createRef(t, table.getOrderField()));
return this.addOrder(this.getTableRef(t));
}
 
public SQLSelect addFieldOrder(String fieldRef) {
return this.addFieldOrder(this.createRef(fieldRef));
public SQLSelect addOrder(TableRef t) {
return this.addOrder(t, true);
}
 
/**
* Add an ORDER BY {@link SQLTable#getOrderField() t.ORDER}.
*
* @param t the table.
* @param fieldMustExist if <code>true</code> then <code>t</code> must be
* {@link SQLTable#isOrdered() ordered}.
* @return this.
* @throws IllegalArgumentException if <code>t</code> isn't ordered and <code>mustExist</code>
* is <code>true</code>.
*/
public SQLSelect addOrder(TableRef t, final boolean fieldMustExist) {
final SQLField orderField = t.getTable().getOrderField();
if (orderField != null)
this.addFieldOrder(t.getField(orderField.getName()));
else if (fieldMustExist)
throw new IllegalArgumentException("table is not ordered : " + t);
return this;
}
 
public SQLSelect addFieldOrder(FieldRef fieldRef) {
return this.addFieldOrder(fieldRef, Order.asc());
}
 
public SQLSelect addFieldOrder(FieldRef fieldRef, final Direction dir) {
return this.addFieldOrder(fieldRef, dir, null);
}
 
public SQLSelect addFieldOrder(FieldRef fieldRef, final Direction dir, final Nulls nulls) {
// with Derby if you ORDER BY w/o mentioning the field in the select clause
// you can't get the table names of columns in a result set.
if (this.base.getServer().getSQLSystem().equals(SQLSystem.DERBY))
if (this.getSQLSystem().equals(SQLSystem.DERBY))
this.addSelect(fieldRef);
 
return this.addRawOrder(fieldRef.getFieldRef());
return this.addRawOrder(fieldRef.getFieldRef() + dir.getSQL() + (nulls == null ? "" : nulls.getSQL()));
}
 
/**
363,20 → 417,11
* @throws IllegalStateException si t n'est pas dans cette requete.
*/
public SQLSelect addOrderSilent(String t) {
try {
this.addOrder(t);
} catch (IllegalArgumentException e) {
// ignore
return this.addOrder(this.getTableRef(t), false);
}
return this;
}
 
// *** select
 
public SQLSelect addSelect(String f) {
return this.addSelect(f, null);
}
 
/**
* Ajoute un champ au SELECT.
*
414,10 → 459,6
return this;
}
 
public SQLSelect addSelect(String f, String function) {
return this.addSelect(this.createRef(f, false), function);
}
 
/**
* Ajoute une fonction d'un champ au SELECT.
*
471,14 → 512,10
return this;
}
 
public SQLSelect addSelectStar(String table) {
return this.addSelectStar(this.base.getTable(table));
}
 
// *** from
 
public SQLSelect addFrom(SQLTable table) {
return this.addFrom(table, null);
public SQLSelect addFrom(SQLTable table, String alias) {
return this.addFrom(new AliasedTable(table, alias));
}
 
/**
485,55 → 522,17
* Explicitely add a table to the from clause. Rarely needed since tables are auto added by
* addSelect(), setWhere() and addJoin().
*
* @param table the table to add.
* @param alias table alias, can be <code>null</code>.
* @param t the table to add.
* @return this.
*/
public SQLSelect addFrom(SQLTable table, String alias) {
this.from.add(this.declaredTables.add(alias, table));
public SQLSelect addFrom(TableRef t) {
this.from.add(this.declaredTables.add(t));
return this;
}
 
// *** where
 
public Where createWhereJ(String f1, String op, String f2) {
return new Where(this.base.getFieldChecked(f1), op, this.base.getField(f2));
}
 
public Where createWhereS(String f1, String op, String scalar) {
return new Where(this.base.getFieldChecked(f1), op, scalar);
}
 
/**
* Renvoie une clause WHERE. Attention utilise une heuristique pour trouver la bonne méthode.
* L'algo est si <code>s</code> est un champ de la base, alors on utilise createWhereJ() sinon
* createWhereS().
*
* @param field un champ de la base.
* @param op l'opérateur.
* @param s un nom de champ ou une valeur.
* @return la clause WHERE correspondante.
* @see #createWhereJ(String, String, String)
* @see #createWhereS(String, String, String)
*/
Where createWhere(String field, String op, String s) {
boolean isField;
try {
isField = this.base.getField(s) != null;
} catch (IllegalArgumentException e) {
isField = false;
}
if (isField)
return this.createWhereJ(field, op, s);
else
return this.createWhereS(field, op, s);
}
 
Where createWhere(String f1, String op, int scalar) {
return new Where(this.createRef(f1), op, scalar);
}
 
/**
* Change la clause where de cette requete.
*
* @param w la nouvelle clause, <code>null</code> pour aucune clause.
553,14 → 552,10
return this;
}
 
public SQLSelect setWhere(String field, String op, String s) {
return this.setWhere(this.createWhere(field, op, s));
public SQLSelect setWhere(FieldRef field, String op, int i) {
return this.setWhere(new Where(field, op, i));
}
 
public SQLSelect setWhere(String field, String op, int i) {
return this.setWhere(this.createWhere(field, op, i));
}
 
/**
* Ajoute le Where passé à celui de ce select.
*
587,17 → 582,6
// simple joins (with foreign field)
 
/**
* Add a join to this SELECT.
*
* @param joinType can be INNER, LEFT or RIGHT.
* @param fk the full name of a foreign key, eg 'BATIMENT.ID_SITE'.
* @return the added join.
*/
public SQLSelectJoin addJoin(String joinType, String fk) {
return this.addJoin(joinType, this.base.getFieldChecked(fk));
}
 
/**
* Add a join to this SELECT. Eg if <code>f</code> is |BATIMENT.ID_SITE|, then "join SITE on
* BATIMENT.ID_SITE = SITE.ID" will be added.
*
605,14 → 589,10
* @param f a foreign key, eg |BATIMENT.ID_SITE|.