miércoles, 1 de septiembre de 2010

Brooks's law

adding manpower to a late software project makes it later

How to vanish terror of deadlines and expectations

It's not my job to “manage” someone else's expectations. It's their job to manage their own expectations. It's my job to do my best and to communicate clearly.

Kent Beck
Extreme Programming Explained

viernes, 6 de agosto de 2010

JavaScript Class using JSON prototype


/// <summary>
/// Class that represents a customer of our store.
/// The constructor receives the name of the customer
/// </summary>
/// <param name="firstName"> First name of the customer.
/// <param name="lastName"> Last name of the customer.
function Customer(firstName, lastName)
{
// Properties
this.FirstName = firstName;
this.LastName = lastName;
}

Customer.prototype = {

/// <summary>
/// Returns the first name of the customer
/// </summary>
GetFirstName: function()
{
return this.FirstName;
},

/// <summary>
/// Returns the last name of the customer
/// </summary>
GetLastName: function()
{
return this.LastName;
},
...
}


Usage:


var aCustomer = new Customer("Pablo","Bustos");
alert("Hello " + aCustomer.GetFirstName());

Good programmers

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.

Refactoring: Improving the Design of Existing Code by Martin Fowler

jueves, 8 de julio de 2010

miércoles, 7 de julio de 2010

Buenos videos de Uncle Bob (Robert Martin, autor de Clean Code)

http://www.objectmentor.com/videos/video_index.html

lunes, 5 de julio de 2010

Exceptions de jetty para retornar http status codes

Usando jetty, puedes arrojar un status code, con mensaje incluido, de la sgte manera:

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
throw new HttpException(404, "not found jeje");
}

jueves, 1 de julio de 2010

Wrap your Exception as a RuntimeException when it is not of your method's business

A method is not required to declare in its throws clause any subclasses of RuntimeException that might be thrown during the execution of the method but not caught.


package exceptions;

public class RuntimeExceptionTest {

public class TestException extends Exception {

}

public static void main(String[] args) {
RuntimeExceptionTest test = new RuntimeExceptionTest();
try {
test.throwWrappedTestExceptionAsRuntimeException();
} catch (Exception e) {
System.out.println("exception catched:\n");
e.printStackTrace();
}
}

private void throwTestException() throws TestException {
throw new TestException();
}


public void throwWrappedTestExceptionAsRuntimeException() {
try {
throwTestException();
} catch (TestException e) {
throw new RuntimeException(e);
}
}
}

Notification rather than logging

¿Te ha pasado que el log ensucia?:

Location location = tracker.getCurrentLocation();
for (Filter filter : filters) {
filter. selectFor(location);
if (logger. isInfoEnabled()) {
logger. info("Filter " + filter.getName() + ", " + filter.getDate()
+ " selected for " + location.getName()
+ ", is current: " + tracker.isCurrent(location));
}
}


Solución:

Location location = tracker.getCurrentLocation();
for (Filter filter : filters) {
filter. selectFor(location);
support.notifyFiltering(tracker, location, filter);
}
Otros beneficios:
  • Mientras programas, no te preocupas de escribir un string concatenando objetos, déjalo para el final.
  • El traspaso del software al área de soporte de tu empresa se complementará dándoles la clase Support, en ella están todos los monitoreos o alarmas que deben capturar.
  • No debes inicializar un Logger de log4j en cada clase que creas (sino sólo en caso de que quieras hacer un log.debug mientras programas)
  • Los logs dejan de ser un string que se escribe "a la rápida", pues deben ser pensados realmente como solución a un requerimiento implícito del departamento de operaciones de tu empresa.
  • En cada método de support no sólo puedes poner un logger en disco, sino también un registro en BD o cualquier otra cosa, usa la encapsulación.

Ref:

lunes, 21 de junio de 2010

Cómo convertir encoding en java tipo iconv, ej: UTF-8 a latin1


import org.apache.commons.io.IOUtils;

public class Iconv {

public static void iconv(InputStream in, OutputStream out, Charset inCharset, Charset outCharset) throws IOException {
InputStreamReader reader = new InputStreamReader(in,inCharset);
OutputStreamWriter writer = new OutputStreamWriter(out,outCharset);
IOUtils.copy(reader,writer);
writer.close();
}



Cómo se usa:


public static void main(String[] args) throws Exception {
utf8ToLatin1();
latin1ToUtf8();
}

private static void latin1ToUtf8() throws Exception {
FileInputStream in = new FileInputStream("/home/pablo/Desktop/workspace/test/files/textoLatin1.txt");
FileOutputStream out = new FileOutputStream("/tmp/textoLatin1ToUTF8.txt");
iconv(in, out, Charset.forName("latin1"), Charset.forName("UTF-8"));
out.close();
}

private static void utf8ToLatin1() throws Exception {
FileInputStream in = new FileInputStream("/home/pablo/Desktop/workspace/test/files/textoUTF8.txt");
FileOutputStream out = new FileOutputStream("/tmp/textoUTF8ToLatin1.txt");
iconv(in, out, Charset.forName("UTF-8"), Charset.forName("latin1"));
out.close();
}


Entrada:


pablo@pablo-desktop:~/Desktop/workspace/test/files$ file --mime texto*
textoLatin1.txt: text/plain; charset=iso-8859-1
textoUTF8.txt: text/plain; charset=utf-8


Resultado:

pablo@pablo-desktop:~/Desktop/workspace/test/files$ file --mime /tmp/texto*
/tmp/textoLatin1ToUTF8.txt: text/plain; charset=utf-8
/tmp/textoUTF8ToLatin1.txt: text/plain; charset=iso-8859-1

martes, 15 de junio de 2010

Cómo ver el contenido de un jar para saber donde esta una clase que se deba incluir

pablo@pablo-desktop:~/bea/user_projects/workspaces/workSpaceStudio/TimerService$ jar -tf /home/pablo/bea/wlserver_10.0/server/lib/weblogic.jar | grep ApplicationException
com/sun/java/xml/ns/javaee/ApplicationExceptionType$1.class
com/sun/java/xml/ns/javaee/ApplicationExceptionType$Factory.class
com/sun/java/xml/ns/javaee/ApplicationExceptionType.class
com/sun/java/xml/ns/javaee/impl/ApplicationExceptionTypeImpl.class
schemacom_bea_xml/javaname/com/sun/java/xml/ns/javaee/ApplicationExceptionType.xsb
weblogic/application/ApplicationException.class
weblogic/j2ee/descriptor/ApplicationExceptionBean.class
weblogic/j2ee/descriptor/ApplicationExceptionBeanImpl$Helper.class
weblogic/j2ee/descriptor/ApplicationExceptionBeanImpl$SchemaHelper.class
weblogic/j2ee/descriptor/ApplicationExceptionBeanImpl$SchemaHelper2.class
weblogic/j2ee/descriptor/ApplicationExceptionBeanImpl.class
weblogic/j2ee/descriptor/ApplicationExceptionBeanImplBeanInfo.class
weblogic/management/ApplicationException.class
pablo@pablo-desktop:~/bea/user_projects/workspaces/workSpaceStudio/TimerService$

lunes, 24 de mayo de 2010

Proxy en apache

no recuerdo si sirven estos 2 comandos:

sudo apt-get install libapache2-mod-proxy-html
sudo a2enmod proxy

pero bueno, lo que sí servía:

sudo vim /etc/apache2/sites-available/default


Order deny,allow
Allow from all


ProxyPass /google http://www.google.cl/
ProxyPassReverse /google http://www.google.cl/



sudo /etc/init.d/apache2 restart

martes, 18 de mayo de 2010

Cómo iterar e imprimir enums en Java


private enum stats {
pings, opened, closed, queueEmpty, gets, releases, timeouts;
private int count=0;
public void add() {
count++;
}
};

private String getStatsString() {
EnumSet set = EnumSet.allOf(stats.class);
HashMap map = new HashMap();
for (stats stat : set) {
map.put(stat.toString(), stat.count);
}
return map.toString();
}

private void logStats() {
log.info("stats del pool: "+getStatsString());
}

sprintf a la Java con String.format

Si bien es cosa de gustos, creo que se ve más ordenado usar String.format en caso de grandes concatenaciones:


public class Sprintf {

public static void main(String[] args) {
String nombre = "Juan";
String apellido = "Riquelme";
int edad = 54;

String concatenacion;

concatenacion = "nombre: "+nombre+", apellido: "+
apellido+", edad: "+edad;
System.out.println(concatenacion);

concatenacion = String.format("nombre: %s, apellido: %s, edad: %d",
nombre, apellido, edad);
System.out.println(concatenacion);
}

}

lunes, 3 de mayo de 2010

Mysql 5.0.3 acepta varchars de mas de 255 caracteres

Para los que seguían pensando lo contrario:

Values in VARCHAR columns are variable-length strings. The length can be specified as a value from 0 to 255 before MySQL 5.0.3, and 0 to 65,535 in 5.0.3 and later versions.

http://dev.mysql.com/doc/refman/5.0/en/char.html

jueves, 29 de abril de 2010

Google translator para language detection

Ref: google apis

Prueba con inglés:

pablo@pablo-desktop:~$ curl -e http://www.fcwm.cl \
'http://ajax.googleapis.com/ajax/services/language/detect?v=1.0&
q=hello%20world'
{"responseData": {"language":"en","isReliable":false,"confidence":0.114892714}, "responseDetails": null, "responseStatus": 200}

Prueba con italiano:

pablo@pablo-desktop:~$ curl -e http://www.fcwm.cl \
'http://ajax.googleapis.com/ajax/services/language/detect?v=1.0&
q=ciao+a+tutti'
{"responseData": {"language":"it","isReliable":false,"confidence":0.29042974}, "responseDetails": null, "responseStatus": 200}

Prueba con español:

pablo@pablo-desktop:~$ curl -e http://www.fcwm.cl \
'http://ajax.googleapis.com/ajax/services/language/detect?v=1.0&
q=hola+a+todos'
{"responseData": {"language":"es","isReliable":false,"confidence":0.28695157}, "responseDetails": null, "responseStatus": 200}

Prueba de detección de español con mayor "confidence" al agregar más palabras:

pablo@pablo-desktop:~$ curl -e http://www.fcwm.cl \
'http://ajax.googleapis.com/ajax/services/language/detect?v=1.0&
q=hola+a+todos+los+cabros+de+la+cuadra'
{"responseData": {"language":"es","isReliable":true,"confidence":0.6409442}, "responseDetails": null, "responseStatus": 200}

Cómo setear el content-type y el charset en la respuesta de un restlet

Papita:

@Override
public Representation getRepresentation(Variant variant) {
if (MediaType.TEXT_XML.equals(variant.getMediaType())) {
...
StringRepresentation representation = new StringRepresentation(xmlText,
MediaType.TEXT_XML, Language.ENGLISH, CharacterSet.UTF_8);
return representation;
}
}

jueves, 22 de abril de 2010

Whole word search en java usando regex


Pattern myPattern = Pattern.compile("\\bSebastián Piñera\\b",
Pattern.CASE_INSENSITIVE | Pattern.DOTALL | Pattern.MULTILINE
| Pattern.UNICODE_CASE | Pattern.CANON_EQ);

String text;
Matcher matcher;

text = "de la pradera camión\nSebastián Piñera";
matcher = myPattern.matcher(text);
System.out.println(matcher.find());

text = "clorox de la pradera Sebastián Piñera jaja";
matcher.reset(text);
System.out.println(matcher.find());

text = "clorox de la pradera jaja";
matcher.reset(text);
System.out.println(matcher.find());


(Ojo con el uso eficiente del "matcher" mediante el método "reset")

Imprimirá:


true
true
false


Ref: http://www.regular-expressions.info/java.html

lunes, 12 de abril de 2010

Export en shell para que java tenga output en UTF8

Hay que hacer un declare de LANG, para que aparezca en el export de la sgte manera:


$ export
...
declare -x LANG="en_US.UTF-8"

miércoles, 31 de marzo de 2010

PHP - cómo darse cuenta de un error de insert por duplicate key


$result = mysql_query($query);
if (!$result) {
if (mysql_errno()==1062) { //Duplicate entry
log_info("user already created");
}
else {
throw new Exception("Invalid query, error: " . mysql_error(),$query);
}
}

miércoles, 24 de marzo de 2010

Cómo generar un jar de json

1. Download http://www.json.org/java/json.zip from json.org. Save it in a some directory, which I'll call %DOWNLOAD_HOME%.

2. Unzip it. Be sure you preserve the archive's directory structure (/org/json/) when you unzip the file.

3. Change directory into %DOWNLOAD_HOME%\org\json

4. Compile the files by running “javac *.java”. At least, this worked for me. There is no build.xml or anything, and it just seemed to compile into classes nicely.

5. CD back into %DOWNLOAD_HOME%

6. Create a jar file called json.jar. The syntax is something like:

jar -cvf json.jar org\json\*.class

Ref: http://processing.org/discourse/yabb2/YaBB.pl?board=Integrate;action=display;num=1163101573

miércoles, 10 de marzo de 2010

SQL - cómo separar las condiciones de join de las condiciones de negocio

Típica consulta:

SELECT r.nombre, c.nombre
FROM Region r, Ciudad c
WHERE r.idregion=c.idregion AND c.fechafundacion>='1810-01-01'


En ella, el where mezcla condiciones de join (r.idregion=c.idregion) y de negocio (c.fechafundacion>='1810-01-01'):


En la sgte consulta, en el join+using aislamos las condiciones de join. En el where aislamos las condiciones de negocio:


SELECT r.nombre, c.nombre
FROM Region r JOIN Ciudad c USING (idregion)
WHERE c.fechafundacion>='1810-01-01'

martes, 2 de febrero de 2010

Buscador de texto tipo google en MySQL

Se puede usar el feature de FULLTEXT Indexing and Searching de mysql:

http://www.petefreitag.com/item/477.cfm

Pool de threads nativo en java

LinkedBlockingQueue queue = new LinkedBlockingQueue();
pool = new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTimeMs,TimeUnit.MILLISECONDS,queue);

CandidateFetcher fetcher = new CandidateFetcher(candidate); //implements Runnable
pool.execute(fetcher);

while(pool.getActiveCount()>0){
log.info("pool.getActiveCount(): "+pool.getActiveCount()+", waitUntilAllFetchesAreDone, go to sleep");
Thread.sleep(5000);
}
log.info("pool.getActiveCount(): 0, terminaron todos");

jueves, 28 de enero de 2010

Cómo no olvidar implementar un método en java

Usar UnsupportedOperationException, ej:


private String fetchHtmlDePagina(int pagina) {
// TODO Auto-generated method stub
throw new UnsupportedOperationException("TODO");
//return null;
}

martes, 19 de enero de 2010

Zend Class Type Hints

Usar comentarios de la sgte manera:

/* @var $myVar Test */

$myVar = getClass();

$myVar->

martes, 12 de enero de 2010

Bash - Aliases within a script

#!/bin/bash
# alias.sh

shopt -s expand_aliases
# Must set this option, else script will not expand aliases.


# First, some fun.
alias Jesse_James='echo "\"Alias Jesse James\" was a 1959 comedy starring Bob Hope."'
Jesse_James

Ref: http://tldp.org/LDP/abs/html/aliases.html