mardi 26 janvier 2010

sql : requete imbrique

Comment faire pour recuperer la version max d'un contrat ou les contrat existe en plusieurs versions ?

SELECT numero_contrat,version, idClient FROM contrat c WHERE (select c2.version FROM contrat WHERE c2.numero_contrat = c.numero_contrat)

Comment tester si des resultats sont renvoyés pour requetes SQL?
SELECT 1 FROM contrat c WHERE c.idClient > 1000

cette requête est bien plus rapide qu'un count. En effet, le résultat est une constante de N lignes.

mercredi 20 janvier 2010

java: web Tomcat authentifications simple

voici, la configuration à mettre en place pour obtenir une authentification par role sous Tomcat :

Voici la section du web.xml au sein de laquelle on ajoute un role et une security constraint :

<code>
<security-constraint>
<display-name>ressourcesProtegees</display-name>
<web-resource-collection>
<web-resource-name>jsp</web-resource-name>
<description>pages jsp</description>
<url-pattern>/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<description>verifie que l'utilisateur a ete authentifie</description>
<role-name>authentifie</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>FORM</auth-method>
<realm-name>authentifie</realm-name>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/erreurLogin.jsp</form-error-page>
</form-login-config>
</login-config>
<security-role>
<description>utilisateur a ete authentifie</description>
<role-name>authentifie</role-name>
</security-role></code>

Puis, il faut ajouter une jsp avec des attributs de form ayant un nom particulier (une action nommé j_security_check et 2 champ nommé j_username et j_password) , comme suit :

<code>

<form action="j_security_check" method="post">
<fieldset id="connexion">
<legend>Connexion</legend>
<p>
<label for="reqStrLogin">Login :</label>
<input id="reqStrLogin" type="text" name="j_username" value="login"/>
<label for="reqStrPAssword">Mot de passe :</label>
<input id="reqStrPassword" type="password" name="j_password" value="password"/>
</p>
</fieldset>
<p class="submit">
<input id="submit" name="submit" type="submit" value="Connexion"/>
</p>
<p>
<a id="nouvelAbonne" href="nouvelUtilisateur.jsp">Vous n'etes pas inscrit, Inscrivez-vous des maintenant</a>
</p>
</form>
</code>
</html>

Il faut aussi configurer les server (Context.xml) avec une datasource et un Realm (Server.xml") sur tomcat 6:

il faut declarer une datasource dans le Context.xml
<code>
<!-- ressources jdbc -->
<Resource name="jdbc/bddApp" auth="Container" type="javax.sql.DataSource"
driverClassName="org.postgresql.Driver" url="jdbc:postgresql://127.0.0.1:5432/bddApp"
username="toto" password="toto" maxActive="20" maxIdle="10"
maxWait="-1" />
</code>

il faut aussi déclarer le Realm asscocié avec bon nom JNDI (ici par BDD)

<code><Realm className="org.apache.catalina.realm.DataSourceRealm" dataSourceName="jdbc/bddApp" debug="99" localDataSource="true" roleNameCol="role" userCredCol="password" userNameCol="nom" userRoleTable="utilisateurs_roles" userTable="utilisateurs"/></code>

Attention : il faut évidemment ajouter une table de role et de user dans la base avec les noms de colonnes spécifiés (ici password ,nom et role)

java : ToStringBuilder et Reflexion

Voici, un petit exemple qui permet de faire une méthode ToString simplement et de manière générique :


/**
*
*/
package com.tools.config.properties.generic;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
* @author enwoo
*
*/
public class SimpleToStringBuilder {

/**
* cree une chaine toString de tout les valeurs des getters
* @param obj
* @return une chaine de cararctere
*/
@SuppressWarnings("unchecked")
public static String toString(Object obj) {

if(obj == null)
{
return "null";
}

StringBuilder builder = new StringBuilder();
builder.append(String.format("id obj = [%s]\n",obj.hashCode()));

Class cl = obj.getClass();

Method [] methods = cl.getDeclaredMethods();

// pour chacune des methodes
for (Method method : methods)
{
// test si c'est un getter
String nomDeMethode = method.getName();

if(Modifier.isPublic(method.getModifiers()) && nomDeMethode.matches("(get[A-Z0-9]+[a-zA-Z0-9]+)") && method.getParameterTypes().length == 0)
{
Field champ = obtenirLeChampAssocieAuGetter(cl, nomDeMethode);
String nomDuChamp = champ.getName();

try {
builder.append(String.format("[%s] => [%s]\n",nomDuChamp ,method.invoke(obj)));
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
{
System.out.println(nomDeMethode);
}
}

return builder.toString();
}

/**
* @param cl
* @param nomDeMethode
* @return
*/
@SuppressWarnings("unchecked")
private static Field obtenirLeChampAssocieAuGetter(Class cl, String nomDeMethode) {
Field champ = null;
String nomDuChampAttendu = devineNomDuChamp(nomDeMethode);
try {
champ = cl.getDeclaredField(nomDuChampAttendu);
} catch (SecurityException e) {
System.err.println(String.format("Le getter nommme [%s] n'a pas de champ associe [%s]",nomDeMethode,nomDuChampAttendu));
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
return champ;
}

/**
* transforme un nom de getter en nom du champ associe
* @param chaine
* @return
*/
private static String devineNomDuChamp(String nomDuGetter)
{
return nomDuGetter.substring(3,4).toLowerCase() + nomDuGetter.substring(4);
}
}



Voici un second exemple, utilisant des invocations de méthodes :


public static void fillBean(Object beanARemplir,Map parameters)
{
Method [] methods = beanARemplir.getClass().getMethods();

String nomAttribut;
String nomMethode;

for (Method method : methods) {

nomMethode = method.getName();

if(nomMethode.startsWith("set"))
{
// la methode est un setter
nomAttribut = nomMethode.substring(3).toLowerCase();

if(parameters.containsKey(nomAttribut))
{
try {
method.invoke(beanARemplir, parameters.get(nomAttribut));
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}

mardi 5 janvier 2010

launchAnyWhere

J'ai récemment eu un problème avec une installation d'une vielle application JRules 5.3 ... L'installation se fait via launchAnywhere mais ne fonctionne pas ... et affiche une erreur bizarre ... comme suit :




Il s'agit d'un problème de VM ... Pour résoudre cela:

il faut lancer le programme en ligne de commande et préciser l'option VM :
monExe.exe LAX_VM "C:\Program Files\Java\j2sdk1.4.2\bin\java.exe"

voilou !!!

oracle : se connecter avec un user particulier

C'est tout bête mais comme je ne le fais pas souvent, j'oublie :

il faut évidemment setter son ORACLE_SID :
export export ORACLE_SID=uneInstanceBDD

Puis pour lancer un script avec un user particulier (ici toto)

Pour se logger ... puis lancer le script suivant (/temp/monScript.sql)
sqlplus toto/toto
SQL> @/temp/monScript.sql

Pour lancer le script suivant directement (/temp/monScript.sql)
sqlplus toto/toto @/temp/monScript.sql

De plus, il est possible de spooler manuellement et a conditiopn d'avoir les droits d'ecriture ;-) ...
SQL>spool monLog.txt
SQL> @/temp/monScript.sql
SQL>spool off