Przeglądaj źródła

changing outputter to annotation loader

Klaas, Wilfried 6 lat temu
rodzic
commit
388f839515

+ 2 - 0
.gitignore

@@ -9,3 +9,5 @@ SimpleServo\.txt
 dependency-reduced-pom\.xml
 
 \.settings/
+
+examples/Blink\.txt

+ 5 - 0
pom.xml

@@ -170,5 +170,10 @@
 			<artifactId>commons-lang3</artifactId>
 			<version>3.4</version>
 		</dependency>
+		<dependency>
+			<groupId>org.reflections</groupId>
+			<artifactId>reflections</artifactId>
+			<version>0.9.10</version>
+		</dependency>
 	</dependencies>
 </project>

+ 0 - 31
src/main/java/de/mcs/tools/sps/FORMAT.java

@@ -1,31 +0,0 @@
-/**
- * MCS Media Computer Software
- * <one line to give the program's name and a brief idea of what it does.>
- * Copyright (C) 2018 by Wilfried Klaas
- * Project: SPSEmulator
- * File: FORMAT.java
- * EMail: W.Klaas@gmx.de
- * Created: 02.12.2018 wklaa
- * 
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- * 
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>
- */
-package de.mcs.tools.sps;
-
-/**
- * @author wklaa
- *
- */
-public enum FORMAT {
-  HEX, TPSTXT, HEXTXT
-}

+ 7 - 2
src/main/java/de/mcs/tools/sps/HEXTextOutputter.java

@@ -10,16 +10,16 @@ import java.io.OutputStreamWriter;
 import java.io.Writer;
 import java.util.List;
 
+import de.mcs.tools.sps.annotations.SPSOutputter;
 import de.mcs.tools.sps.mnemonic.Mnemonic;
 
 /**
  * @author w.klaas
  *
  */
+@SPSOutputter(name = "HEXTXT")
 public class HEXTextOutputter implements Outputter {
 
-  public final String FORMAT = "TPSTXT";
-
   /**
    * 
    */
@@ -49,4 +49,9 @@ public class HEXTextOutputter implements Outputter {
     }
   }
 
+  @Override
+  public String getDefaultExtension() {
+    return ".txt";
+  }
+
 }

+ 7 - 2
src/main/java/de/mcs/tools/sps/IntelHEXOutputter.java

@@ -7,16 +7,16 @@ import java.io.OutputStream;
 import java.util.List;
 
 import de.mcs.tools.IntelHex;
+import de.mcs.tools.sps.annotations.SPSOutputter;
 import de.mcs.tools.sps.mnemonic.Mnemonic;
 
 /**
  * @author w.klaas
  *
  */
+@SPSOutputter(name = "HEX")
 public class IntelHEXOutputter implements Outputter {
 
-  public final String FORMAT = "HEX";
-
   /**
    * 
    */
@@ -39,4 +39,9 @@ public class IntelHEXOutputter implements Outputter {
     intelHex.writeHexStream(output, data);
   }
 
+  @Override
+  public String getDefaultExtension() {
+    return ".hex";
+  }
+
 }

+ 2 - 0
src/main/java/de/mcs/tools/sps/Outputter.java

@@ -16,4 +16,6 @@ public interface Outputter {
 
   void output(List<Mnemonic> mnemonics, OutputStream output);
 
+  String getDefaultExtension();
+
 }

+ 50 - 15
src/main/java/de/mcs/tools/sps/SPSAssembler.java

@@ -25,18 +25,25 @@ import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.lang.annotation.Annotation;
 import java.nio.charset.Charset;
 import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Set;
 
 import org.apache.commons.lang3.StringUtils;
+import org.reflections.Reflections;
+import org.reflections.util.ClasspathHelper;
+import org.reflections.util.ConfigurationBuilder;
 
+import de.mcs.tools.sps.annotations.SPSOutputter;
 import de.mcs.tools.sps.exceptions.IllegalArgument;
 import de.mcs.tools.sps.exceptions.SyntaxError;
 import de.mcs.tools.sps.mnemonic.CALL;
@@ -64,10 +71,11 @@ public class SPSAssembler {
   private static final String INCLUDE_FILE = ".include";
   private static final String END_MACRO_DEFINITION = ".endmacro";
   private static final String START_MACRO_DEFINITION = ".macro";
+  private static final String DEFAULT_PACKAGE_FILTER = "de.mcs.tools.sps"; //$NON-NLS-1$
   private static File source;
   private static HARDWARE destination;
   private static File destinationFile;
-  private static FORMAT outputFormat;
+  private static String outputFormat;
   private static File includes;
 
   private int lineNumber;
@@ -78,6 +86,7 @@ public class SPSAssembler {
   private boolean inMacro;
   private Macro actualMacro;
   private Map<String, Macro> macros;
+  private static Outputter outputter;
 
   @SwitchOption(shortKey = 'h', longKey = "help", name = "help", help = "show this help page", required = false, defaultValue = false)
   public static void doHelp(boolean value) {
@@ -89,7 +98,7 @@ public class SPSAssembler {
 
   @StringOption(shortKey = 'f', longKey = "format", name = "format", defaultValue = "HEX", help = "the output format. HEX: IntelHEX, TPSTXT: TPS programming text", required = false)
   public static void setOutputFormat(String value) {
-    outputFormat = FORMAT.valueOf((value.toUpperCase()));
+    outputFormat = value.toUpperCase();
   }
 
   @StringOption(shortKey = 'd', longKey = "hardware", name = "hardware system", defaultValue = "HOLTEK", help = "the hardware system to compile to. Passible options are: HOLTEK, ATMEGA8, ARDUINOSPS, TINYSPS", required = false)
@@ -127,23 +136,25 @@ public class SPSAssembler {
       destination = HARDWARE.HOLTEK;
 
       CommandlineProcessor.processCommandline(SPSAssembler.class, args);
+
+      registerOutputter();
+
       if ((source == null) || (!source.exists())) {
         CommandlineProcessor.showHelp(
             String.format("source file null or not found. %s", (source == null) ? "" : source.getAbsolutePath()));
         System.exit(-1);
       }
-      System.out.printf("source file: %s \r\n", source.getName());
+
       if (destinationFile == null) {
         String name = source.getName();
         name = name.substring(0, source.getName().lastIndexOf("."));
-        String ext = ".hex";
-        if (outputFormat.equals(FORMAT.TPSTXT)) {
-          ext = ".txt";
-        }
+        String ext = outputter.getDefaultExtension();
         destinationFile = new File(source.getParentFile(), name + ext);
       }
+
+      System.out.printf("source file: %s \r\n", source.getName());
       System.out.printf("destination file: %s \r\n", destinationFile.getName());
-      System.out.printf("output format: %s \r\n", outputFormat.name());
+      System.out.printf("output format: %s \r\n", outputFormat);
       System.out.println();
 
       try {
@@ -170,6 +181,36 @@ public class SPSAssembler {
     }
   }
 
+  /**
+   * @throws InstantiationException
+   * @throws IllegalAccessException
+   * @throws Exception
+   */
+  private static void registerOutputter() throws InstantiationException, IllegalAccessException, Exception {
+    Set<Class<?>> outputClasses = registerOutputter(SPSOutputter.class);
+    for (Class<?> outClass : outputClasses) {
+      SPSOutputter annotation = outClass.getAnnotation(SPSOutputter.class);
+      if (annotation.name().equalsIgnoreCase(outputFormat)) {
+        outputter = (Outputter) outClass.newInstance();
+      }
+    }
+
+    if (outputter == null) {
+      throw new Exception(String.format("can't find outputter for format: %s", outputFormat));
+    }
+  }
+
+  private static Set<Class<?>> registerOutputter(Class<? extends Annotation>... annotationClasses) {
+    ConfigurationBuilder builder = new ConfigurationBuilder();
+    builder.addUrls(ClasspathHelper.forPackage(DEFAULT_PACKAGE_FILTER));
+    Reflections reflections = new Reflections(builder);
+    Set<Class<?>> classes = new HashSet<Class<?>>();
+    for (Class<? extends Annotation> class1 : annotationClasses) {
+      classes.addAll(reflections.getTypesAnnotatedWith(class1));
+    }
+    return classes;
+  }
+
   /**
    * @param mnemonics
    * @throws IOException
@@ -177,13 +218,7 @@ public class SPSAssembler {
    */
   private static void outputFile(List<Mnemonic> mnemonics) throws IOException, FileNotFoundException {
     try (FileOutputStream output = new FileOutputStream(destinationFile)) {
-      if (outputFormat.equals(FORMAT.HEX)) {
-        new IntelHEXOutputter().output(mnemonics, output);
-      } else if (outputFormat.equals(FORMAT.TPSTXT)) {
-        new TPSTextOutputter().output(mnemonics, output);
-      } else if (outputFormat.equals(FORMAT.HEXTXT)) {
-        new HEXTextOutputter().output(mnemonics, output);
-      }
+      outputter.output(mnemonics, output);
     } finally {
     }
   }

+ 7 - 3
src/main/java/de/mcs/tools/sps/TPSTextOutputter.java

@@ -12,21 +12,20 @@ import java.util.List;
 
 import org.apache.commons.lang3.StringUtils;
 
+import de.mcs.tools.sps.annotations.SPSOutputter;
 import de.mcs.tools.sps.mnemonic.Mnemonic;
 
 /**
  * @author w.klaas
  *
  */
+@SPSOutputter(name = "TPSTXT")
 public class TPSTextOutputter implements Outputter {
 
-  public final String FORMAT = "TPSTXT";
-
   /**
    * 
    */
   public TPSTextOutputter() {
-    // TODO Auto-generated constructor stub
   }
 
   /* (non-Javadoc)
@@ -60,4 +59,9 @@ public class TPSTextOutputter implements Outputter {
     return b.toString();
   }
 
+  @Override
+  public String getDefaultExtension() {
+    return ".txt";
+  }
+
 }

+ 22 - 0
src/main/java/de/mcs/tools/sps/annotations/SPSOutputter.java

@@ -0,0 +1,22 @@
+/**
+ * 
+ */
+package de.mcs.tools.sps.annotations;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Retention(RUNTIME)
+@Target(TYPE)
+/**
+ * @author w.klaas
+ *
+ */
+public @interface SPSOutputter {
+
+  String name();
+
+}

+ 8 - 0
src/main/java/de/mcs/tools/sps/annotations/package-info.java

@@ -0,0 +1,8 @@
+/**
+ * 
+ */
+/**
+ * @author w.klaas
+ *
+ */
+package de.mcs.tools.sps.annotations;