feat: Terminada la documentación y establecida la configuración.

main
KyMAN 2 months ago
parent da7199c549
commit 1d85f017b8
  1. 4
      Actividad1/aleatorios/build/built-jar.properties
  2. BIN
      Actividad1/aleatorios/build/classes/aleatorios/Aleatorios.class
  3. BIN
      Actividad1/aleatorios/dist/aleatorios.jar
  4. 11
      Actividad1/aleatorios/src/aleatorios/Aleatorios.java
  5. 4
      Actividad1/ordenarNumeros/build/built-jar.properties
  6. 0
      Actividad1/ordenarNumeros/build/classes/.netbeans_automatic_build
  7. 0
      Actividad1/ordenarNumeros/build/classes/.netbeans_update_resources
  8. BIN
      Actividad1/ordenarNumeros/build/classes/ordenarnumeros/OrdenarNumeros.class
  9. BIN
      Actividad1/ordenarNumeros/dist/ordenarNumeros.jar
  10. 2
      Actividad1/ordenarNumeros/src/ordenarnumeros/OrdenarNumeros.java
  11. 73
      Actividad2/colaborar/build.xml
  12. 4
      Actividad2/colaborar/build/built-jar.properties
  13. 0
      Actividad2/colaborar/build/classes/.netbeans_automatic_build
  14. 0
      Actividad2/colaborar/build/classes/.netbeans_update_resources
  15. BIN
      Actividad2/colaborar/build/classes/colaborar/Colaborar$1.class
  16. BIN
      Actividad2/colaborar/build/classes/colaborar/Colaborar$2.class
  17. BIN
      Actividad2/colaborar/build/classes/colaborar/Colaborar$3.class
  18. BIN
      Actividad2/colaborar/build/classes/colaborar/Colaborar$4.class
  19. BIN
      Actividad2/colaborar/build/classes/colaborar/Colaborar$5.class
  20. BIN
      Actividad2/colaborar/build/classes/colaborar/Colaborar$6.class
  21. BIN
      Actividad2/colaborar/build/classes/colaborar/Colaborar.class
  22. 32
      Actividad2/colaborar/dist/README.TXT
  23. BIN
      Actividad2/colaborar/dist/colaborar.jar
  24. 3
      Actividad2/colaborar/manifest.mf
  25. 1771
      Actividad2/colaborar/nbproject/build-impl.xml
  26. 8
      Actividad2/colaborar/nbproject/genfiles.properties
  27. 2
      Actividad2/colaborar/nbproject/private/private.properties
  28. 12
      Actividad2/colaborar/nbproject/private/private.xml
  29. 95
      Actividad2/colaborar/nbproject/project.properties
  30. 15
      Actividad2/colaborar/nbproject/project.xml
  31. 287
      Actividad2/colaborar/src/colaborar/Colaborar.java
  32. 2
      Actividad2/lenguaje/build/built-jar.properties
  33. BIN
      Actividad2/lenguaje/build/classes/lenguaje/Lenguaje$1.class
  34. BIN
      Actividad2/lenguaje/build/classes/lenguaje/Lenguaje$2.class
  35. BIN
      Actividad2/lenguaje/build/classes/lenguaje/Lenguaje.class
  36. BIN
      Actividad2/lenguaje/dist/lenguaje.jar
  37. 9
      Actividad2/lenguaje/nbproject/private/private.xml
  38. 144
      Actividad2/lenguaje/src/lenguaje/Lenguaje.java
  39. 575
      README.md

@ -1,4 +1,4 @@
#Mon, 26 Feb 2024 17:35:52 +0100
#Thu, 07 Mar 2024 01:37:31 +0100
/home/DAM2024/PSP01_Tarea/aleatorios=
/home/DAM2024/PSP01_Tarea/Actividad1/aleatorios=

Binary file not shown.

@ -11,6 +11,11 @@ import java.util.ArrayList;
* @author kyman
*/
public class Aleatorios {
// Configuración.
private static final int numero_de_numeros = 100;
private static final int[] rango_aleatorio = {0, 100};
// Configuración.
/**
* @param args the command line arguments
@ -20,10 +25,10 @@ public class Aleatorios {
ArrayList<Integer> numeros_aleatorios = new ArrayList<>();
for(int i = 0; i < 100; i ++)
numeros_aleatorios.add((int)(Math.random() * 101));
for(int i = 0; i < numero_de_numeros; i ++)
numeros_aleatorios.add((int)(Math.random() * (rango_aleatorio[1] + 1 - rango_aleatorio[0])) + rango_aleatorio[0]);
for(int i = 0; i < 100; i ++)
for(int i = 0; i < numero_de_numeros; i ++)
System.out.println("" + numeros_aleatorios.get(i));
}

@ -1,4 +1,4 @@
#Mon, 26 Feb 2024 17:36:30 +0100
#Thu, 07 Mar 2024 01:37:28 +0100
/home/DAM2024/PSP01_Tarea/ordenarNumeros=
/home/DAM2024/PSP01_Tarea/Actividad1/ordenarNumeros=

@ -21,7 +21,7 @@ public class OrdenarNumeros {
// TODO code application logic here
Scanner entrada = new Scanner(System.in);
ArrayList<Integer> lista = new ArrayList<Integer>();
ArrayList<Integer> lista = new ArrayList<>();
while(entrada.hasNextInt())
lista.add(entrada.nextInt());

@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- You may freely edit this file. See commented blocks below for -->
<!-- some examples of how to customize the build. -->
<!-- (If you delete it and reopen the project it will be recreated.) -->
<!-- By default, only the Clean and Build commands use this build script. -->
<!-- Commands such as Run, Debug, and Test only use this build script if -->
<!-- the Compile on Save feature is turned off for the project. -->
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
<!-- in the project's Project Properties dialog box.-->
<project name="colaborar" default="default" basedir=".">
<description>Builds, tests, and runs the project colaborar.</description>
<import file="nbproject/build-impl.xml"/>
<!--
There exist several targets which are by default empty and which can be
used for execution of your tasks. These targets are usually executed
before and after some main targets. They are:
-pre-init: called before initialization of project properties
-post-init: called after initialization of project properties
-pre-compile: called before javac compilation
-post-compile: called after javac compilation
-pre-compile-single: called before javac compilation of single file
-post-compile-single: called after javac compilation of single file
-pre-compile-test: called before javac compilation of JUnit tests
-post-compile-test: called after javac compilation of JUnit tests
-pre-compile-test-single: called before javac compilation of single JUnit test
-post-compile-test-single: called after javac compilation of single JUunit test
-pre-jar: called before JAR building
-post-jar: called after JAR building
-post-clean: called after cleaning build products
(Targets beginning with '-' are not intended to be called on their own.)
Example of inserting an obfuscator after compilation could look like this:
<target name="-post-compile">
<obfuscate>
<fileset dir="${build.classes.dir}"/>
</obfuscate>
</target>
For list of available properties check the imported
nbproject/build-impl.xml file.
Another way to customize the build is by overriding existing main targets.
The targets of interest are:
-init-macrodef-javac: defines macro for javac compilation
-init-macrodef-junit: defines macro for junit execution
-init-macrodef-debug: defines macro for class debugging
-init-macrodef-java: defines macro for class execution
-do-jar: JAR building
run: execution of project
-javadoc-build: Javadoc generation
test-report: JUnit report generation
An example of overriding the target for project execution could look like this:
<target name="run" depends="colaborar-impl.jar">
<exec dir="bin" executable="launcher.exe">
<arg file="${dist.jar}"/>
</exec>
</target>
Notice that the overridden target depends on the jar target and not only on
the compile target as the regular run target does. Again, for a list of available
properties which you can use, check the target you are overriding in the
nbproject/build-impl.xml file.
-->
</project>

@ -0,0 +1,4 @@
#Thu, 07 Mar 2024 01:40:43 +0100
/home/DAM2024/PSP01_Tarea/Actividad2/colaborar=

@ -0,0 +1,32 @@
========================
BUILD OUTPUT DESCRIPTION
========================
When you build an Java application project that has a main class, the IDE
automatically copies all of the JAR
files on the projects classpath to your projects dist/lib folder. The IDE
also adds each of the JAR files to the Class-Path element in the application
JAR files manifest file (MANIFEST.MF).
To run the project from the command line, go to the dist folder and
type the following:
java -jar "colaborar.jar"
To distribute this project, zip up the dist folder (including the lib folder)
and distribute the ZIP file.
Notes:
* If two JAR files on the project classpath have the same name, only the first
JAR file is copied to the lib folder.
* Only JAR files are copied to the lib folder.
If the classpath contains other types of files or folders, these files (folders)
are not copied.
* If a library on the projects classpath also has a Class-Path element
specified in the manifest,the content of the Class-Path element has to be on
the projects runtime path.
* To set a main class in a standard Java project, right-click the project node
in the Projects window and choose Properties. Then click Run and enter the
class name in the Main Class field. Alternatively, you can manually type the
class name in the manifest Main-Class element.

Binary file not shown.

@ -0,0 +1,3 @@
Manifest-Version: 1.0
X-COMMENT: Main-Class will be added automatically by build

File diff suppressed because it is too large Load Diff

@ -0,0 +1,8 @@
build.xml.data.CRC32=50193e74
build.xml.script.CRC32=cc88e93b
build.xml.stylesheet.CRC32=f85dc8f2@1.110.0.48
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
nbproject/build-impl.xml.data.CRC32=50193e74
nbproject/build-impl.xml.script.CRC32=0a9661e5
nbproject/build-impl.xml.stylesheet.CRC32=12e0a6c2@1.110.0.48

@ -0,0 +1,2 @@
compile.on.save=true
user.properties.file=/home/kyman/snap/netbeans/93/build.properties

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="0"/>
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
<group>
<file>file:/home/DAM2024/PSP01_Tarea/Actividad2/colaborar/src/colaborar/Colaborar.java</file>
<file>file:/home/DAM2024/PSP01_Tarea/Actividad2/colaborar/src/colaborar/ColaborarB.java</file>
<file>file:/home/DAM2024/PSP01_Tarea/Actividad2/colaborar/src/colaborar/Cliente.java</file>
<file>file:/home/DAM2024/PSP01_Tarea/Actividad2/colaborar/src/colaborar/Servidor.java</file>
</group>
</open-files>
</project-private>

@ -0,0 +1,95 @@
annotation.processing.enabled=true
annotation.processing.enabled.in.editor=false
annotation.processing.processor.options=
annotation.processing.processors.list=
annotation.processing.run.all.processors=true
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
build.classes.dir=${build.dir}/classes
build.classes.excludes=**/*.java,**/*.form
# This directory is removed when the project is cleaned:
build.dir=build
build.generated.dir=${build.dir}/generated
build.generated.sources.dir=${build.dir}/generated-sources
# Only compile against the classpath explicitly listed here:
build.sysclasspath=ignore
build.test.classes.dir=${build.dir}/test/classes
build.test.results.dir=${build.dir}/test/results
# Uncomment to specify the preferred debugger connection transport:
#debug.transport=dt_socket
debug.classpath=\
${run.classpath}
debug.modulepath=\
${run.modulepath}
debug.test.classpath=\
${run.test.classpath}
debug.test.modulepath=\
${run.test.modulepath}
# Files in build.classes.dir which should be excluded from distribution jar
dist.archive.excludes=
# This directory is removed when the project is cleaned:
dist.dir=dist
dist.jar=${dist.dir}/colaborar.jar
dist.javadoc.dir=${dist.dir}/javadoc
dist.jlink.dir=${dist.dir}/jlink
dist.jlink.output=${dist.jlink.dir}/colaborar
excludes=
includes=**
jar.compress=false
javac.classpath=
# Space-separated list of extra javac options
javac.compilerargs=
javac.deprecation=false
javac.external.vm=true
javac.modulepath=
javac.processormodulepath=
javac.processorpath=\
${javac.classpath}
javac.source=19
javac.target=19
javac.test.classpath=\
${javac.classpath}:\
${build.classes.dir}
javac.test.modulepath=\
${javac.modulepath}
javac.test.processorpath=\
${javac.test.classpath}
javadoc.additionalparam=
javadoc.author=false
javadoc.encoding=${source.encoding}
javadoc.html5=false
javadoc.noindex=false
javadoc.nonavbar=false
javadoc.notree=false
javadoc.private=false
javadoc.splitindex=true
javadoc.use=true
javadoc.version=false
javadoc.windowtitle=
# The jlink additional root modules to resolve
jlink.additionalmodules=
# The jlink additional command line parameters
jlink.additionalparam=
jlink.launcher=true
jlink.launcher.name=colaborar
main.class=colaborar.Colaborar
manifest.file=manifest.mf
meta.inf.dir=${src.dir}/META-INF
mkdist.disabled=false
platform.active=default_platform
run.classpath=\
${javac.classpath}:\
${build.classes.dir}
# Space-separated list of JVM arguments used when running the project.
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
# To set system properties for unit tests define test-sys-prop.name=value:
run.jvmargs=
run.modulepath=\
${javac.modulepath}
run.test.classpath=\
${javac.test.classpath}:\
${build.test.classes.dir}
run.test.modulepath=\
${javac.test.modulepath}
source.encoding=UTF-8
src.dir=src
test.src.dir=test

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.java.j2seproject</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
<name>colaborar</name>
<source-roots>
<root id="src.dir"/>
</source-roots>
<test-roots>
<root id="test.src.dir"/>
</test-roots>
</data>
</configuration>
</project>

@ -0,0 +1,287 @@
/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Main.java to edit this template
*/
package colaborar;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
/**
*
* @author kyman
*/
public class Colaborar {
// Configuración.
private static final int numero_instancias = 10;
private static final String path_absoluto = "/home/DAM2024/PSP01_Tarea";
private static final String lenguaje_path = path_absoluto + "/Actividad2/lenguaje/dist/lenguaje.jar";
private static final int puerto = 45338;
// Configuración.
public static boolean trabajando = true;
private static ServerSocket socket;
private static final ArrayList<Socket> clientes = new ArrayList<>();
private static final ArrayList<PrintWriter> salidas = new ArrayList<>();
private static boolean ocupado = false;
private static int clientes_cerrados = 0;
private static Scanner entrada;
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
if(iniciar_servidor()){
iniciar_terminal();
for(int i = 0; i < numero_instancias; i ++)
try {
Process proceso = Runtime.getRuntime().exec("java -jar " + lenguaje_path + " " + ((i + 1) * 10) + " " + path_absoluto + "/diccionario.txt");
BufferedReader entrada = new BufferedReader(new InputStreamReader(proceso.getInputStream()));
BufferedReader errores = new BufferedReader(new InputStreamReader(proceso.getErrorStream()));
new Thread(new Runnable(){
@Override
public void run() {
try {
String mensaje;
while((mensaje = entrada.readLine()) != null)
System.out.println(mensaje);
} catch (IOException excepcion) {
Colaborar.excepcion(excepcion);
}
}
}).start();
new Thread(new Runnable(){
@Override
public void run() {
try {
String mensaje;
while((mensaje = errores.readLine()) != null)
System.out.println(mensaje);
} catch (IOException excepcion) {
Colaborar.excepcion(excepcion);
}
}
}).start();
} catch (IOException excepcion) {
Colaborar.excepcion(excepcion);
}
}else
System.out.println("Hubo un error al intentar lanzar el Socket servidor en el puerto " + puerto + ".");
}
public static void excepcion(Exception exception){
System.out.println(exception.getMessage());
System.out.println(Arrays.toString(exception.getStackTrace()));
}
private static void iniciar_terminal(){
new Thread(new Runnable(){
@Override
public void run() {
entrada = new Scanner(System.in);
while(trabajando){
String mensaje = entrada.nextLine();
if(!mensaje.trim().isEmpty())
switch(mensaje){
case "close", "cerrar", "bye", "exit", "terminar" -> cerrar();
default -> System.out.println("Comando desconocido.");
}
}
entrada.close();
}
}).start();
}
private static boolean iniciar_servidor(){
boolean exito = false;
try{
new Thread(new Runnable(){
@Override
public void run() {
try{
socket = new ServerSocket(puerto);
while(trabajando){
Socket cliente = socket.accept();
PrintWriter salida = new PrintWriter(cliente.getOutputStream());
int i = 0;
int l = clientes.size();
for(; i < l; i++)
if(clientes.get(i) == null)
break;
if(i == l){
clientes.add(cliente);
salidas.add(salida);
}else{
clientes.set(i, cliente);
salidas.set(i, salida);
}
escuchar(i, new BufferedReader(new InputStreamReader(cliente.getInputStream())));
}
}catch(IOException excepcion){
// ColaborarB.excepcion(excepcion);
}
}
}).start();
exito = true;
}catch(Exception excepcion){
Colaborar.excepcion(excepcion);
}
return exito;
}
private static void escuchar(int i, BufferedReader entrada){
new Thread(new Runnable(){
@Override
public void run() {
String mensaje;
try{
while((mensaje = entrada.readLine()) != null){
System.out.println("SERVIDOR - REC => " + mensaje);
switch(mensaje){
case "permiso" -> {
if(ocupado)
enviar(i, "permiso No");
else{
ocupado = true;
enviar(i, "permiso Sí");
}
}
case "terminado" -> ocupado = false;
case "cerrar" -> {
if((clientes_cerrados += 1) == numero_instancias)
cerrar();
}
}
}
entrada.close();
}catch(IOException excepcion) {
// ColaborarB.excepcion(excepcion);
}
cerrar_cliente(i);
}
}).start();
}
private static boolean enviar(int i, String mensaje){
boolean estado = false;
try{
new Thread(new Runnable() {
@Override
public void run() {
PrintWriter salida = salidas.get(i);
System.out.println("SERVIDOR - ENV => " + mensaje);
salida.println(mensaje);
salida.flush();
}
}).start();
estado = true;
}catch(Exception excepcion){
Colaborar.excepcion(excepcion);
}
return estado;
}
private static boolean cerrar_cliente(int i){
boolean exito = false;
Socket cliente = clientes.get(i);
if(cliente != null){
try {
PrintWriter salida = salidas.get(i);
if(salida != null)
salida.close();
cliente.close();
clientes.set(i, null);
exito = true;
} catch (IOException excepcion) {
Colaborar.excepcion(excepcion);
}
}
return exito;
}
public static boolean cerrar(){
boolean exito = false;
trabajando = false;
if(entrada != null){
System.out.println("La aplicación ha terminado. Por favor, presione \"ENTER\" para salir de la aplicación.");
entrada.close();
}
if(socket != null){
for(int i = 0, l = clientes.size(); i < l; i ++)
cerrar_cliente(i);
try {
socket.close();
exito = true;
} catch (IOException excepcion) {
Colaborar.excepcion(excepcion);
}
}
return exito;
}
}

@ -1,4 +1,4 @@
#Mon, 26 Feb 2024 18:04:18 +0100
#Thu, 07 Mar 2024 01:37:18 +0100
/home/DAM2024/PSP01_Tarea/Actividad2/lenguaje=

Binary file not shown.

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project-private xmlns="http://www.netbeans.org/ns/project-private/1">
<editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="0"/>
<open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/2">
<group>
<file>file:/home/DAM2024/PSP01_Tarea/Actividad2/lenguaje/src/lenguaje/Lenguaje.java</file>
</group>
</open-files>
</project-private>

@ -4,11 +4,15 @@
*/
package lenguaje;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Arrays;
/**
@ -16,6 +20,18 @@ import java.util.Arrays;
* @author kyman
*/
public class Lenguaje {
// Configuración.
private static final int puerto = 45338;
private static final String host = "localhost";
private static int numero_de_palabras = 40;
private static String path = "../../diccionario.txt";
private static final String alfabeto = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private static final float probabilidad_nueva_letra = .8f;
// Configuración.
private static boolean trabajando = true;
private static PrintWriter salida;
/**
* @param args the command line arguments
@ -23,26 +39,111 @@ public class Lenguaje {
public static void main(String[] args) {
// TODO code application logic here
int numero_de_palabras = Integer.parseInt(args[0]);
String path = args[1];
String alfabeto = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int l = alfabeto.length();
try (BufferedWriter archivo = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path)))) {
for(int i = 0; i < numero_de_palabras; i ++){
String palabra = "";
while(palabra.length() < 3 || Math.random() < .8)
palabra += alfabeto.charAt((int)(Math.random() * l));
System.out.println(Arrays.toString(args));
if(args.length == 2){
numero_de_palabras = Integer.parseInt(args[0]);
path = args[1];
}
try {
try {
archivo.append(palabra + "\n");
}catch(IOException excepcion){
Lenguaje.excepcion(excepcion);
Socket socket = new Socket(host, puerto);
salida = new PrintWriter(socket.getOutputStream());
BufferedReader lectura = new BufferedReader(new InputStreamReader(socket.getInputStream()));
new Thread(new Runnable(){
@Override
public void run() {
String mensaje;
int palabras_creadas = 0;
try{
while((mensaje = lectura.readLine()) != null){
System.out.println("CLIENTE - REC => " + mensaje);
String[] resultados = mensaje.split(" ");
switch(resultados[0]){
case "permiso" -> {
if(resultados[1].equals("Sí")){
escribir_palabra();
enviar("terminado");
System.out.println("Palabra #" + palabras_creadas + " de " + numero_de_palabras + ".");
if((palabras_creadas += 1) >= numero_de_palabras){
enviar("cerrar");
trabajando = false;
}
}
if(trabajando)
try {
Thread.sleep((long) (Math.random() * 100));
enviar("permiso");
} catch (InterruptedException excepcion) {
Lenguaje.excepcion(excepcion);
}
}
}
}
lectura.close();
} catch (IOException excepcion) {
Lenguaje.excepcion(excepcion);
}
}
}).start();
enviar("permiso");
}catch(IOException ex){
escribir_fichero();
}
}
private static boolean enviar(String mensaje){
boolean estado = false;
try{
new Thread(new Runnable(){
@Override
public void run() {
System.out.println("CLIENTE - ENV => " + mensaje);
salida.println(mensaje);
salida.flush();
}
}).start();
estado = true;
}catch(Exception excepcion){
Lenguaje.excepcion(excepcion);
}
return estado;
}
public static String crear_palabra(){
String palabra = "";
int l = alfabeto.length();
while(palabra.length() < 3 || Math.random() < probabilidad_nueva_letra)
palabra += alfabeto.charAt((int)(Math.random() * l));
return palabra;
}
public static void escribir_palabra(){
File archivo = new File(path);
if(!archivo.exists())
try {
archivo.createNewFile();
} catch (IOException excepcion) {
Lenguaje.excepcion(excepcion);
}
try (BufferedWriter escritura = new BufferedWriter(new FileWriter(archivo, true))) {
escritura.append(Lenguaje.crear_palabra() + "\n");
}catch(FileNotFoundException excepcion){
Lenguaje.excepcion(excepcion);
}catch(IOException excepcion){
@ -50,6 +151,11 @@ public class Lenguaje {
}
}
public static void escribir_fichero(){
for(int i = 0; i < numero_de_palabras; i ++)
escribir_palabra();
}
private static void excepcion(Exception exception){
System.out.println(exception.getMessage());

@ -1,5 +1,576 @@
# PSP01_Tarea
PSP01_Tarea
> Este ejercicio fue hecho sin mirar el temario y entregado fuera de plazo por motivos agenos al ciclo, por lo que independientemente de resultados, agradecer al profesor a cargo de la asignatura por mirarlo igualmente pese a dichas condiciones, así por el apoyo ofrecido. También quiero que quede de aviso para otros posibles compañeros que quieran hacer uso de este contenido por posiblemente no ceñirse a lo requerido en la asignatura. Sea como sea, espero sea útil para aprender y reciclarse como lo fue para mi.
https://git.k3y.pw/DAM2024/PSP01_Tarea
Conjunto de ejercicios para controlar entradas y salidas de una aplicación así como escritura y sincronía entre aplicaciones Java. Dicho ejercicio está publicado en la siguiente URL Git:
https://git.k3y.pw/DAM2024/PSP01_Tarea
> Antes de empezar, aclarar que todos los archivos de Scripts JAVA contendrán un apartado de configuración si éstos lo requieren, en el inicio de la clase, encapsulados entre dos comentarios de línea llamados "Configuración".
## ordernarNumeros
Esta aplicación simplemente cogerá una entrada de números dados por el usuario mediante el terminal donde una vez ponga cualquier cosa que no sea un valor numérico entero, éste detendrá el proceso de espera de más números, cogerá la lista de números dados y los ordenará de menor a mayor y los imprimirá por pantalla.
```mermaid
flowchart TD
S(["Solicitar número"])
O(["Ordenar números"])
M(["Mostrar números ordenados"])
S -->|"¿Es número?"| S
S -->|"¿No es número?"| O
O --> M
```
La aplicación es muy sencilla y no tiene configuración alguna. El tema del ordenamiento numérico se hace a partir del método "sort" del ArrayList donde se almacenan los números, y usado el método estático "naturalOrder" de la clase nativa Comparator. También decir que se hace uso de un objeto Scanner por simplicidad de uso para la escucha de entrada del usuario.
### Resultado de ejemplo
```txt
run:
56
1
87
9
4
terminar
1
4
9
56
87
BUILD SUCCESSFUL (total time: 13 seconds)
```
## aleatorios
Esta aplicación simplemente generará 100 valores numéricos enteros aleatorios entre 0 y 100, ambos incluídos. Una vez generados, éste los imprimirá por pantalla.
```mermaid
flowchart TD
G(["Generar números aleatorios"])
M(["Mostrar números aleatorios"])
G --> M
```
No tiene más complicación, sin embargo, dejé configurable los siguientes parámetros:
- **numero_de_numeros**: Número de números enteros aleatorios que se van a crear.
- **rango_aleatorio**: Tabla de dos valores numéricos enteros positivos que indican el rango en el que se generarán dichos números enteros aleatorios, incluyendo los dados. El primero ha de ser menor que el segundo.
### Resultado de ejemplo
```txt
run:
97
5
65
12
91
2
14
67
56
52
81
51
9
46
16
91
56
52
14
89
20
23
71
51
38
69
100
48
100
66
2
61
73
53
25
82
30
54
40
28
83
47
69
61
92
28
39
49
58
68
83
23
14
100
25
70
25
68
88
48
92
60
16
17
79
81
4
3
56
19
71
42
89
87
23
93
61
20
61
15
36
68
87
80
13
3
94
77
53
34
53
80
58
24
6
24
45
42
47
37
BUILD SUCCESSFUL (total time: 0 seconds)
```
## Tubería
Las dos aplicaciones anteriores pueden coexistir y funcionar entre ellas mediante una tubería en un terminal o consola de comandos, mandando la salida de la aplicación *aleatorios* contra la entrada de *ordenarNumeros*. El comando sería el siguiente:
```sh
#!/bin/bash
directorio=`dirname $(readlink -f "$0")`
java -jar $directorio/Actividad1/aleatorios/dist/aleatorios.jar | java -jar $directorio/Actividad1/ordenarNumeros/dist/ordenarNumeros.jar
```
En el Script, también existente en el proyecto, establece el directorio raíz donde se encuentra, que viene siendo el Path raíz del proyecto, y luego cogerá el Path relativo a cada JAR de cada aplicación. También puede llamarse directamente, como en el ejemplo siguiente, donde se usará una ruta relativa:
```sh
#!/bin/bash
java -jar Actividad1/aleatorios/dist/aleatorios.jar | java -jar Actividad1/ordenarNumeros/dist/ordenarNumeros.jar
```
```mermaid
flowchart TD
A[aleatorios]
O[ordenarNumeros]
A --> O
```
### Resultados de ejemplo
```txt
kyman@kyman-GS75-9SE:/home/DAM2024/PSP01_Tarea$ ./tuberia.sh
0
1
2
4
5
6
7
8
11
12
12
13
14
14
14
19
20
22
25
26
27
27
28
29
29
30
30
32
33
34
34
37
37
38
38
40
41
41
41
43
44
45
46
46
46
48
49
50
50
51
51
51
51
53
55
57
58
60
61
62
64
64
65
65
67
68
68
68
68
70
71
71
71
73
75
75
77
78
79
81
82
82
83
83
84
86
86
87
88
88
88
92
92
93
96
96
97
98
99
100
kyman@kyman-GS75-9SE:/home/DAM2024/PSP01_Tarea$ java -jar Actividad1/aleatorios/dist/aleatorios.jar | java -jar Actividad1/ordenarNumeros/dist/ordenarNumeros.jar
0
0
2
2
2
3
4
4
5
5
5
6
8
8
8
9
9
11
12
13
13
16
16
17
17
17
21
25
26
26
26
26
27
30
31
33
33
34
34
36
37
38
38
38
40
41
43
43
44
45
45
46
47
47
48
49
49
50
50
52
53
54
55
55
56
56
61
63
63
65
65
66
66
68
68
68
70
75
77
77
79
79
82
83
83
85
87
87
89
90
90
91
94
94
95
95
96
96
100
100
kyman@kyman-GS75-9SE:/home/DAM2024/PSP01_Tarea$
```
## lenguaje
Esta aplicación crea un diccionario de un idioma inventado a partir de juntar, aleatoriamente, letras. Para su ejecución requiere de 2 parámetros de entrada, los cuales son:
1. El número de palabras a crear.
2. El Path donde se almacenará el diccionario.
> Por defecto, ambos parámetros están definidos en la configuración de la aplicación a 40 palabras y el Path del fichero diccionario en el raíz del proyecto con el nombre "diccionario.txt".
La idea es que el programa añada al fichero diccionario cada palabra generada, recargando el fichero, añadiendo al Buffer la nueva palabra en una nueva línea, escribiendo el fichero y cerrando el Buffer.
```mermaid
flowchart TD
C{"Crear nueva palabra aleatoria"}
D["Archivo diccionario"]
O["Objeto File"]
A{"Crear archivo diccionario"}
B[Buffer]
P["Nueva palabra"]
E{"Escribir archivo diccionario"}
C -->|Crear| P
C --> D
D -->|"Abrir con"| O
O -->|"Sí existe"| B
O -->|"No existe"| A
A --> B
P -->|"Añadir en"| B
B --> E
```
La creación de la palabra se basa en un diccionario String que contendrá los caracteres a usar que se encuentra en la configuración. Para su creación se establecen dos condiciones: que sea al menos de 3 caracteres; y se vayan añadiendo caracteres si la condición aleatoria así lo determine. La probabilidad de nueva letra no es más que un "Math.random" condicionado a un valor decimal entre 0 y 1. A mayor sea el número más letras probables contendrá la nueva palabra.
```mermaid
flowchart TD
P[Palabra]
C{"length < 3 || \nRand < probabilidad"}
L["Nueva letra"]
X(["Nueva palabra creada"])
P -->|Mientras| C
C -->|Sí| L
C -->|No| X
L -->|"Se añade a"| P
```
### Socket
En el siguiente ejercicio a éste, se especifica literalmente *que lance al menos 10 instancias de la aplicación "lenguaje"*, donde entiendo que la aplicación es el JAR de la aplicación "lenguage". Indagué un poco sobre Java, viendo la imposibilidad de éste de analizar si un fichero está en uso o no, donde hay librerías que permiten un uso de bloqueo de ficheros o detectar un uso por bloqueo mediante Excepción, pero en ningún caso me funcionó cara la mera apertura del fichero, por lo que me vi en la obligación de crear un Socket de comunicación bidireccional entre las diferentes instancias de la aplicación "lenguaje" como clientes, sobre un servidor "colaborar", quien contendría el semáforo entre aplicaciones mediante un simple valor Booleano que determine si el archivo está siendo usado por alguna de las instancias o no, donde en caso de estar en uso, ésta espere un tiempo aleatorio para volver a intentar la petición.
```mermaid
flowchart TD
subgraph lenguage
X{"Crear nueva palabra"}
S[Socket]
E{Esperar}
W{"Escribir diccionario"}
L{"Liberar diccionario"}
E --> S
X --> S
end
C[Colaborar]
S -->|"¿Está en uso?"| C
C -->|Sí| E
C -->|No| W
W --> L
L -.-> C
L --> X
```
> Si no fuese la ejecución de instancias de aplicación y sí de simples instancias de la clase "Lenguaje", el formato sería distinto, siendo regulado por semáforos o un simple Booleano que condicione, incluso, al estar trabajando en este caso sobre objetos, directamente con un "wait" donde se irían desbloqueando los procesos entre ellos, simplificando enormemente la aplicación.
Mediante este sistema evitamos que la sobreescritura por parte de cualquiera de las instancias de aplicación ejecutadas exista, permitiendo un orden mediante un protocolo de semáforos a un sólo proceso.
La aplicación entiende que si existe el servidor Socket de "colaborar", éste ha de regularse de esta forma; de lo contrario, actuará como estaba predicho anteriormente.
> Es importante mencionar que hay una serie de salidas que determinan qué hace el Socket tanto para uso local como para uso remoto contra "colaborar".
### Configuración
Los parámtros de configuración para esta aplicación son los siguientes:
- **puerto**: Puerto de red del Socket servidor "colaborar".
- **host**: Host de red del Socket servidor "colaborar".
- **numero_de_palabras**: Número de palabras por defecto a crear en caso de tener una entrada vacía.
- **path**: Path relativo al Path del JAR "lenguaje.jar" donde se almacenará el diccionario.
- **alfabeto**: String con los caracteres a usar para crear las nuevas palabras.
- **probabilidad_nueva_letra**: Valor decimal comprendido entre 0 y 1 que determina la probabilidad de añadir un nuevo caracter a la nueva palabra.
## colaborar
Esta aplicación ejecutará varias instancias de la aplicación "lenguage" para que éstas escriban, de forma ordenada y sincronizada, un diccionario común. Para llevar a cabo dicha tarea se hará uso de un Socket que gestione, a modo de semáforo de un único proceso, el acceso al fichero diccionario de todas las instancias ejecutadas de la aplicación. Todas estas instancias serán lanzadas por la propia aplicación "colaborar". Uba vez terminen todas las instancias de almacenar sus palabras al diccionario, la aplicación mostrará un mensaje indicando que terminó y que presiones "Enter" para poder cerrar la aplicación.
> Si no fuese la ejecución de instancias de aplicación y sí de simples instancias de la clase "Lenguaje", el formato sería distinto, siendo regulado por semáforos o un simple Booleano que condicione, incluso, al estar trabajando en este caso sobre objetos, directamente con un "wait" donde se irían desbloqueando los procesos entre ellos, simplificando enormemente la aplicación.
> El programa no se cierra por el hecho de que cuenta con una entrada de terminal por si se quiere cerrar la aplicación mediante una orden. Si se termina la ejecución del programa, queda el objeto Scanner abierto, el cual, al ser de interactuación humana, éste ha de ser cerrado por el usuario, y de ahí que muestr el mensaje pidiendo que se presione "Enter".
```mermaid
flowchart TD
subgraph colaborar
P[Permiso]
O{"Ocupar diccionario"}
OS([Sí])
ON([No])
D{"Desocupar diccionario"}
C{Cerrar}
end
L[lenguage]
L -->|"¿Tiene?"| P
P --> OS
OS --> O
OS -->|"Tiene permiso"| L
P --> ON
ON -->|"No tiene permiso"| L
L -->|"Nueva palabra añadida"| D
L -->|Terminó| C
```
Las instancias de la aplicación "lenguaje" son lanzadas tras haber lanzado el Socket servidor y el terminal. El caso de que el Socket servidor dé un error de inicio, éste lo mostrará y no lanzará nada más, cerrando la aplicación automáticamente.
```mermaid
flowchart TD
S{{"¿Inició el servidor?"}}
T{{"Inicia el terminal"}}
I{{"Ejecuta las instancias cliente"}}
E{{"Imprimir error"}}
SI([Sí])
NO([No])
S --> SI
SI --> T
SI --> I
S --> NO
NO --> E
```
> Si el usuario introduce en la terminal de la aplicación cualquiera de las opciones "close", "cerrar", "bye", "exit" o "terminar", la aplicación mandará orden de cierre a las aplicaciones cliente y se cerrará ella misma.
> Hay elementos que imprimirán por la terminal indicaciones de lo que está haciendo la aplicación durante su ejecución, mayormente para controlar el correcto funcionamiento de los Socket. También imprimirá lo que impriman sobre terminal las instancias de la aplicación "lenguaje" ejecutadas.
El cierre automático de la aplicación cuando los clientes terminan su actividad se lleva a cabo a partir de una variable de control la cual viene siendo un valor numérico entero con valor por defecto 0 pero que a medida que se traen mensajes de cierre de los clientes, éste irá incrementándose. Cuando éste sea igual al número de clientes, la aplicación entederá como que todos los clientes temrinaron y cesará su actividad.
La configuración de esta aplicación es la siguiente:
- **numero_instancias**: Númerom de instancias de la aplicación "lenguaje" va a ejecutar simultáneamente.
- **path_absoluto**: Path absoluto del proyecto raíz. *¡Ojo! No del proyecto Java, sino el proyecto completo del ejercicio.*
- **lenguaje_path**: Path de la aplicación JAR "lenguaje.jar".
- **puerto**: Puerto de trabajo del Socket.
### Documentación
En el ejercicio se establecen ciertas normas cara lo que viene siendo la documentación del ejercicio, pero por falta de tiempo y las circunstancias descritas al inicio de este documento, me vi en la decisión de montar toda documentación requerida sobre MarkDown y así integrarlo dentro del proyecto Git para facilitar tanto su acceso como su visibilidad mediante los componentes integrados en éste como gráficos o formatos de texto rápido mediante marcas por caracter.
Loading…
Cancel
Save