[misMetodos] Expandir Variables de Entorno - expandEnvironmentVariables



Me encontrando en C# la necesidad de expandir una variable de entorno (%PUBLIC%) y ha sido recontra facil:

1
2
3
4
public static string ExpandEnviromentVariable(string source)
{
    return Environment.ExpandEnvironmentVariables(source);
}


Tratando de realizar la misma operacion en java no ha resultado tan facil, pero es posible. La estratégia resulta ser la siguiente:

  • Obtener un mapa del sistema con todas las variables de entorno System.getenv(), mi mapa resulto ser asi:
  • {
     LOCALAPPDATA=C:\Users\Desarollo-VII\AppData\Local,
     ChocolateyLastPathUpdate=marjun1911:39:562018,
     PROCESSOR_LEVEL=16,
     FP_NO_HOST_CHECK=NO,
     M2=C:\dev\apache-maven-3.2.1/bin,
     VS140COMNTOOLS=C:\ProgramFiles(x86)\MicrosoftVisualStudio14.0\Common7\Tools\,
     USERDOMAIN=DESARROLLOVI,
     LOGONSERVER=\\DESARROLLOVI,
     JAVA_HOME=C:\ProgramFiles\Java\jdk1.8.0_91,
     SESSIONNAME=Console,
     ALLUSERSPROFILE=C:\ProgramData,
     PROCESSOR_ARCHITECTURE=AMD64,
     PSModulePath=...,
     SystemDrive=C:,
     ANT_HOME=C:\dev\apache-ant-1.9.7,
     DEV_HOME=C:\dev,
     APPDATA=C:\Users\Desarollo-VII\AppData\Roaming,=A:=A:\,
     USERNAME=Desarollo-VII,
     ChocolateyInstall=C:\ProgramData\chocolatey,
     ProgramFiles(x86)=C:\ProgramFiles(x86),
     JBOSS_HOME_=C:\dev\APPsERVER\jboss-4.2.3.GA,
     CommonProgramFiles=C:\ProgramFiles\CommonFiles,
     Path=..., 
     PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC,
     OS=Windows_NT,
     COMPUTERNAME=DESARROLLOVI,
     JBOSS_HOME=C:\dev\APPsERVER\wildfly-10.1.0.Final,
     PROCESSOR_REVISION=0402,
     CommonProgramW6432=C:\ProgramFiles\CommonFiles,
     ComSpec=C:\Windows\system32\cmd.exe,
     ProgramData=C:\ProgramData,
     ProgramW6432=C:\ProgramFiles,
     HOMEPATH=\Users\Desarollo-VII,
     SystemRoot=C:\Windows,
     TEMP=C:\Users\DESARO~1\AppData\Local\Temp,
     HOMEDRIVE=C:,
     PROCESSOR_IDENTIFIER=AMD64Family16Model4Stepping2,
     USERPROFILE=C:\Users\Desarollo-VII,
     TMP=C:\Users\DESARO~1\AppData\Local\Temp,
     M2_HOME=C:\dev\apache-maven-3.2.1,
     CommonProgramFiles(x86)=C:\ProgramFiles(x86)\CommonFiles,
     ProgramFiles=C:\ProgramFiles,
     PUBLIC=C:\Users\Public,
     NUMBER_OF_PROCESSORS=3,
     windir=C:\Windows,
    }
    


  • Crear un Patter para divir la variable en 2 grupos: uno con la expresion completa y el otro sin los porcentajes (Este seria la key del mapa de variabless)
  • 1
    2
    3
    4
    5
    Pattern pattern = Pattern.compile("%(.*?)%");
    Matcher matcher = pattern.matcher(valorInicial);
    
    String grupoCeroPatronEntrePorcentajes = matcher.group(0);
    String grupoUnoPatronSinPorcentaje = matcher.group(1);
    


  • Luego con la key en la mano, se obtiene el valor del mapa
  • Por ultimo se hace un replace del grupo uno(entre porcentaje) con el value del mapa obtenido con el grupo dos





 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
public static String expandEnvironmentVariables(String valorInicial) {
    String valorRetorno = null;
    Map<String, String> variablesEntorno = System.getenv();

    Pattern pattern = Pattern.compile("%(.*?)%");
    Matcher matcher = pattern.matcher(valorInicial);

    while (matcher.find()) {
        String grupoCeroPatronEntrePorcentajes = matcher.group(0);

        String grupoUnoPatronSinPorcentaje = matcher.group(1);
        String valorVariableEntorno = variablesEntorno.get(grupoUnoPatronSinPorcentaje);

        valorRetorno = valorInicial.replace(grupoCeroPatronEntrePorcentajes, valorVariableEntorno);
    }

    return valorRetorno;
}


Ejemplo

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
System.out.println(expandEnvironmentVariables("%USERPROFILE%\\archivo.txt"));
System.out.println(expandEnvironmentVariables("%APPDATA%\\.minecraft"));
System.out.println(expandEnvironmentVariables("%PUBLIC%\\PepeFolder"));
System.out.println(expandEnvironmentVariables("%WINDIR%\\fonts"));
System.out.println(expandEnvironmentVariables("%JAVA_HOME%\\jre\\bin\\java.exe"));
System.out.println(expandEnvironmentVariables("%JBOSS_HOME%\\bin\\run.bat"));
System.out.println(expandEnvironmentVariables("%M2%"));
System.out.println(expandEnvironmentVariables("%ANT_HOME%"));

/* Outputs:
C:\Users\Desarollo-VII\archivo.txt
C:\Users\Desarollo-VII\AppData\Roaming\.minecraft
C:\Users\Public\PepeFolder
No se encontro la variable : %WINDIR%\fonts
C:\Program Files\Java\jdk1.8.0_91\jre\bin\java.exe
C:\dev\APPsERVER\wildfly-10.1.0.Final\bin\run.bat
C:\dev\apache-maven-3.2.1/bin
C:\dev\apache-ant-1.9.7
*/


Lo unico que habria que validar, es que el mapa no es lo mismo la key PUBLIC o public

[MisMetodos] Definir la raíz del contexto en JBoss

Se necesita crear el archvio de nombre 'jboss-web.xml' en la raiz de 'WEB-INF' con el siguiente contenido:



En mi caso el proyecto se llama auomatizacion.

<?xml version="1.0" ?>
<jboss-web>
    <context-root>/nombreDeLaAplicacion</context-root>
</jboss-web>

según la propia Documentación de Jboss (funciona para 4.2.3.GA)

atributos descripción
context-root Root context of the web-app. It defaults to the filename of the deployment without suffix .war




Traducción al español

El contexto raíz de la aplicación web. El valor predeterminado es el nombre de archivo de despliegue sin el sufijo .war

Esto permite porner el war con el nombre de version e incluso de construccion y que el nombre al que se acceda sea el mismo

[Métodos] Conocer IP donde ejecutamos Java


Para conocer nuestra ip local debemos recurrir a la clase java.net.InetAddress

Esta clase representa una dirección de protocolo de internet(IP) o bueno es lo que la documentación misma dice.

Solo basta con importar la clase, instanciar un objeto de la misma a través del método getLocalHost()

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import java.net.InetAddress;
...
InetAddress ip;
try {
    ip = InetAddress.getLocalHost();
    System.out.print("ipLocal: ");
    System.out.println(ip.getHostAddress());
} catch (UnknownHostException e) {
    e.printStackTrace();
}

La salida será del estilo:
1
ipLocal: 10.0.0.157


También InetAddress nos permitirá conocer el nombre de la pc y el dominio:
1
2
3
4
System.out.print("nombre del PC: ");
System.out.println(ip.getHostName());
System.out.print("dominio del PC: ");
System.out.println(ip.getCanonicalHostName());

1
2
nombre del PC: Dar10-PC
dominio del PC: algunDominio



Ip pública


Para hallar nuestra ip pública debemos recurrir a un servicio como por ejemplo http://checkip.amazonaws.com

Este servicio de amazon, nos devuelve un InputStream con nada más ni nada menos que la ip del solicitando, pero nos vale para obtener nuestra propia ip publica.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
...
URL ipPublica;
BufferedReader in = null;
InputStreamReader isr = null;
try {
    ipPublica = new URL("http://checkip.amazonaws.com");
    isr = new InputStreamReader(ipPublica.openStream());
    in = new BufferedReader(isr);
    String ip = in.readLine(); 
    System.out.print("IP publica: ");
    System.out.println(ip);
} catch (MalformedURLException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} finally {
    try {
        if (in != null) {
            in.close();
        }
        if(isr != null){
            isr.close();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

1
IP publica: aqui va tu ip

[Métodos] Reemplazar caracteres con acento, tildes, signos diacriticos, etc

Mi problema, windows no acepta caracteres diacriticos para nombres de archivos o directorios, como los acentos graves y agudos ( ´ ) y ( ` ), el acento circunflejo ( ^ ), la diéresis ( ¨ ), la virgulilla ( ~ ), la cedilla ( ¸ ), la colita ( ˛ ), la coma ( , ), el doble acento agudo, ( ˝ ), el doble acento grave, ( `` ) , el carón ( ˇ ), el breve ( ˘ ), el macrón ( ˉ ), el anillo ( ˚ ), el punto ( • ) el garfio ( ̉ )
ja lo saque de wikipedia!

Entonces pense en removeer los caracteres que ningún sistema operativo permite.
1
String invalidCharRemoved = fileName.replaceAll("[\\\\/:*?\"<>|]", "");

Este patrón remueve aquellos caracteres que windows nos informa con una vigneta:

Pero aun asi, los acentos, la Ñ que si son admitos en la mayorias de distribuciones de windows siguen estando, pero justo el servidor productivo no era uno de ellos.
La siguiente solucion, aunque torpe, satisfacia la problematica y permitía a la aplicación seguir funcionando:
1
string.replace("á", "").replace("é", "").replace("í", "").replace("ó", "").replace("ú", "").replace("ñ", "")

Aunque funcional, a gusto personal no es aceptable:
1
evaluación desempeño región aledaños --> evaluacin desempeo regin aledaos

Para lo cual encontré 2 posibles soluciones: Java.text.Normalizer y org.apache.commons.lang3.StringUtils

Normalizer

1
2
3
4
5
6
import java.text.Normalizer;
...
private static String normalizeUsingJavaText(String source){
    source = Normalizer.normalize(source, Normalizer.Form.NFD);
    return source.replaceAll("[^\\p{ASCII}]", "");
}

Esto podria ser usado asi:
1
2
3
4
5
public static void main(String[] args){
    String string = "áéíóúñ";
    System.out.println(normalizeUsingJavaText(cadenaLoca()));
    //salida --> aeioun
}


StringUtils


Esta es un dependencia, y por lo cual hay que importarla por ejemplo con maven:
1
2
3
4
5
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.0</version>
</dependency>

Simplemente basta con llamar al metodo stripAccents:
1
2
3
4
5
6
import org.apache.commons.lang3.StringUtils;
...
private static String normalizeUsingApacheStringUtils(String source){
    String input = StringUtils.stripAccents(source);
    return input;
}

Esto lo implemente asi: (Esta fué la solución ganadora)
1
2
3
4
5
public static void main(String[] args){
    String string = "áéíóúñ";       
    System.out.println(normalizeUsingApacheStringUtils(string));
    // salida -> aeioun
}