Java tutorial
/** * Copyright 2011-2016 Asakusa Framework Team. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.asakusafw.modelgen.emitter; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.PrintWriter; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; import javax.tools.Diagnostic; import javax.tools.JavaFileObject; import org.apache.hadoop.io.Writable; import org.junit.After; import org.junit.Before; import com.asakusafw.runtime.io.ModelInput; import com.asakusafw.runtime.io.ModelOutput; import com.asakusafw.runtime.io.RecordEmitter; import com.asakusafw.runtime.io.RecordParser; import com.asakusafw.utils.java.jsr199.testing.VolatileCompiler; import com.asakusafw.utils.java.jsr199.testing.VolatileJavaFile; import com.asakusafw.utils.java.model.syntax.CompilationUnit; import com.asakusafw.utils.java.model.syntax.ModelFactory; import com.asakusafw.utils.java.model.syntax.TypeDeclaration; import com.asakusafw.utils.java.model.util.Emitter; import com.asakusafw.utils.java.model.util.Models; import com.asakusafw.vocabulary.model.DataModel; import com.asakusafw.vocabulary.model.JoinedModel; import com.asakusafw.vocabulary.model.SummarizedModel; /** * Test root for this package. */ public abstract class EmitterTestRoot { /** * */ protected ModelFactory f; /** * ???? */ List<VolatileJavaFile> files; /** * ?? */ VolatileCompiler compiler; /** * ?? * @throws Exception if occur */ @Before public void setUp() throws Exception { f = Models.getModelFactory(); files = new ArrayList<>(); compiler = new VolatileCompiler(); } /** * ?? * @throws Exception ???? */ @After public void tearDown() throws Exception { if (compiler != null) { compiler.close(); } } /** * ??? * @param source * @return */ protected PrintWriter createOutputFor(CompilationUnit source) { StringBuilder buf = new StringBuilder(); TypeDeclaration type = Emitter.findPrimaryType(source); if (source.getPackageDeclaration() != null) { buf.append(source.getPackageDeclaration().toString().replace('.', '/')); buf.append('/'); } buf.append(type.getName().getToken()); VolatileJavaFile file = new VolatileJavaFile(buf.toString()); files.add(file); return new PrintWriter(file.openWriter()); } /** * ? * @return ?? */ protected ClassLoader compile() { if (files.isEmpty()) { throw new AssertionError(); } for (JavaFileObject java : files) { compiler.addSource(java); } compiler.addArguments("-Xlint"); List<Diagnostic<? extends JavaFileObject>> diagnostics = compiler.doCompile(); boolean hasWrong = false; for (Diagnostic<? extends JavaFileObject> d : diagnostics) { if (d.getKind() == Diagnostic.Kind.ERROR || d.getKind() == Diagnostic.Kind.WARNING) { JavaFileObject java = d.getSource(); if (java != null) { try { System.out.println("=== " + java.getName()); System.out.println(java.getCharContent(true)); System.out.println(); System.out.println(); } catch (IOException e) { // ignored } } System.out.println("--"); System.out.println(d.getMessage(Locale.getDefault())); hasWrong = true; } } if (hasWrong) { throw new AssertionError(diagnostics); } return compiler.getClassLoader(); } /** * ??????? * @param loader ? * @param name ?? * @return ? */ protected Object create(ClassLoader loader, String name) { try { Class<?> klass = loader.loadClass("com.example." + name); return klass.newInstance(); } catch (Exception e) { throw new AssertionError(e); } } /** * ?????{@link ModelInput}?? * @param loader ? * @param parser * @param name ?? * @return ? */ @SuppressWarnings("unchecked") protected ModelInput<Object> createInput(ClassLoader loader, RecordParser parser, String name) { try { Class<?> klass = loader.loadClass("com.example." + name); Constructor<?> ctor = klass.getConstructor(RecordParser.class); return (ModelInput<Object>) ctor.newInstance(parser); } catch (Exception e) { throw new AssertionError(e); } } /** * ?????{@link ModelOutput}?? * @param loader ? * @param emitter * @param name ?? * @return ? */ @SuppressWarnings("unchecked") protected ModelOutput<Object> createOutput(ClassLoader loader, RecordEmitter emitter, String name) { try { Class<?> klass = loader.loadClass("com.example." + name); Constructor<?> ctor = klass.getConstructor(RecordEmitter.class); return (ModelOutput<Object>) ctor.newInstance(emitter); } catch (Exception e) { throw new AssertionError(e); } } /** * ???? * @param object ? * @param name ??getter??? * @return ? * @throws Throwable ???? */ public static Object get(Object object, String name) throws Throwable { try { return find(object, name).invoke(object); } catch (InvocationTargetException e) { throw e.getCause(); } catch (Exception e) { throw new AssertionError(e); } } /** * ???? * @param object ? * @param name ??setter??? * @param value ? * @throws Throwable ???? */ public static void set(Object object, String name, Object value) throws Throwable { try { Method method = find(object, name); method.invoke(object, value); } catch (InvocationTargetException e) { throw e.getCause(); } catch (Exception e) { throw new AssertionError(e); } } /** * {@code argument}??{@code object}?? * @param object ? * @param argument ? * @throws Throwable ???? */ public static void copyFrom(Object object, Object argument) throws Throwable { try { Method method = find(object, DataModel.Interface.METHOD_NAME_COPY_FROM); method.invoke(object, argument); } catch (InvocationTargetException e) { throw e.getCause(); } catch (Exception e) { throw new AssertionError(e); } } /** * ??????????????? * @param object ? * @param left ??? * @param right ??? * @throws Throwable ???? */ public static void joinFrom(Object object, Object left, Object right) throws Throwable { try { Method method = find(object, JoinedModel.Interface.METHOD_NAME_JOIN_FROM); method.invoke(object, left, right); } catch (InvocationTargetException e) { throw e.getCause(); } catch (Exception e) { throw new AssertionError(e); } } /** * ???????????????? * @param object ? * @param left ???? * @param right ???? * @throws Throwable ???? */ public static void split(Object object, Object left, Object right) throws Throwable { try { Method method = find(object, JoinedModel.Interface.METHOD_NAME_SPLIT_INTO); method.invoke(object, left, right); } catch (InvocationTargetException e) { throw e.getCause(); } catch (Exception e) { throw new AssertionError(e); } } /** * ???????? * @param object ? * @param argument ??? * @throws Throwable ???? */ public static void startSummarize(Object object, Object argument) throws Throwable { try { Method method = find(object, SummarizedModel.Interface.METHOD_NAME_START_SUMMARIZATION); method.invoke(object, argument); } catch (InvocationTargetException e) { throw e.getCause(); } catch (Exception e) { throw new AssertionError(e); } } /** * ?????? * @param object ? * @param argument ? * @throws Throwable ???? */ public static void combineSummarize(Object object, Object argument) throws Throwable { try { Method method = find(object, SummarizedModel.Interface.METHOD_NAME_COMBINE_SUMMARIZATION); method.invoke(object, argument); } catch (InvocationTargetException e) { throw e.getCause(); } catch (Exception e) { throw new AssertionError(e); } } private static Method find(Object object, String name) { List<Method> found = new ArrayList<>(); for (Method method : object.getClass().getMethods()) { if (method.getName().equals(name)) { found.add(method); } } if (found.size() != 1) { throw new AssertionError(name + found); } return found.get(0); } /** * Writable????????? * @param <T> ? * @param value ? * @return ?? */ @SuppressWarnings("unchecked") protected <T> T restore(T value) { assertThat(value, instanceOf(Writable.class)); Writable writable = (Writable) value; try { ByteArrayOutputStream write = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(write); writable.write(out); out.flush(); ByteArrayInputStream read = new ByteArrayInputStream(write.toByteArray()); ObjectInputStream in = new ObjectInputStream(read); Writable copy = writable.getClass().newInstance(); copy.readFields(in); assertThat(in.read(), is(-1)); assertThat(copy, is((Writable) value)); assertThat(copy.hashCode(), is(value.hashCode())); return (T) copy; } catch (Exception e) { throw new AssertionError(e); } } /** * {@link TableModelEntityEmitter}? */ protected class Table extends TableModelEntityEmitter { Table() { super(Models.getModelFactory(), new File("."), "com.example", Collections.singletonList("Table Model Entity Emitter")); } @Override protected PrintWriter openOutputFor(CompilationUnit source) throws IOException { return createOutputFor(source); } } /** * {@link JoinedModelEntityEmitter}? */ protected class Joined extends JoinedModelEntityEmitter { Joined() { super(Models.getModelFactory(), new File("."), "com.example", Collections.singletonList("Joined Model Entity Emitter")); } @Override protected PrintWriter openOutputFor(CompilationUnit source) throws IOException { return createOutputFor(source); } } /** * {@link SummarizedModelEntityEmitter}? */ protected class Summarized extends SummarizedModelEntityEmitter { Summarized() { super(Models.getModelFactory(), new File("."), "com.example", Collections.singletonList("Summarized Model Entity Emitter")); } @Override protected PrintWriter openOutputFor(CompilationUnit source) throws IOException { return createOutputFor(source); } } /** * {@link ModelInputEmitter}? */ protected class TsvIn extends ModelInputEmitter { TsvIn() { super(Models.getModelFactory(), new File("."), "com.example", Collections.singletonList("TSV Input Emitter")); } @Override protected PrintWriter openOutputFor(CompilationUnit source) throws IOException { return createOutputFor(source); } } /** * {@link ModelInputEmitter}? */ protected class TsvOut extends ModelOutputEmitter { TsvOut() { super(Models.getModelFactory(), new File("."), "com.example", Collections.singletonList("TSV Output Emitter")); } @Override protected PrintWriter openOutputFor(CompilationUnit source) throws IOException { return createOutputFor(source); } } }