Selaa lähdekoodia

Set up repository with initial classes

Sam Jaffe 8 vuotta sitten
vanhempi
commit
69bd32cc55

+ 139 - 0
pom.xml

@@ -0,0 +1,139 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.leumasjaffe</groupId>
+  <artifactId>observer</artifactId>
+  <version>0.1</version>
+  <packaging>jar</packaging>
+
+  <name>observer</name>
+  <url>http://maven.apache.org</url>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+   <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.eclipse.m2e</groupId>
+          <artifactId>lifecycle-mapping</artifactId>
+          <version>1.0.0</version>
+          <configuration>
+            <lifecycleMappingMetadata>
+              <pluginExecutions>
+                <pluginExecution>
+                  <pluginExecutionFilter>
+                    <groupId>org.projectlombok</groupId>
+                    <artifactId>lombok-maven-plugin</artifactId>
+                    <versionRange>[1,)</versionRange>
+                    <goals>
+                      <goal>delombok</goal>
+                    </goals>
+                  </pluginExecutionFilter>
+                  <action>
+                    <ignore />
+                  </action>
+                </pluginExecution>
+              </pluginExecutions>
+            </lifecycleMappingMetadata>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <sourceDirectory>target/generated-sources/delombok</sourceDirectory>
+    <plugins>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.5.1</version>
+        <configuration>
+          <compilerVersion>1.8</compilerVersion>
+          <source>1.8</source>
+          <target>1.8</target>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.projectlombok</groupId>
+        <artifactId>lombok-maven-plugin</artifactId>
+        <version>1.16.18.0</version>
+        <executions>
+          <execution>
+            <id>delombok</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>delombok</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <addOutputDirectory>false</addOutputDirectory>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-jar-plugin</artifactId>
+        <version>2.4</version>
+        <configuration>
+          <archive>
+            <manifest>
+              <addClasspath>true</addClasspath>
+              <classpathPrefix>dependency-jars/</classpathPrefix>
+            </manifest>
+          </archive>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-dependency-plugin</artifactId>
+        <version>2.5.1</version>
+        <executions>
+          <execution>
+            <id>copy-dependencies</id>
+            <phase>package</phase>
+            <goals>
+              <goal>copy-dependencies</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>
+                ${project.build.directory}/dependency-jars/
+              </outputDirectory>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.projectlombok</groupId>
+      <artifactId>lombok</artifactId>
+      <version>1.16.18</version>
+    </dependency>
+    <dependency>
+      <groupId>org.projectlombok</groupId>
+      <artifactId>lombok-maven-plugin</artifactId>
+      <version>1.16.18.0</version>
+      <type>maven-plugin</type>
+    </dependency>
+    <dependency>
+      <groupId>com.google.guava</groupId>
+      <artifactId>guava</artifactId>
+      <version>19.0</version>
+    </dependency>
+    <dependency>
+      <groupId>org.leumasjaffe</groupId>
+      <artifactId>event</artifactId>
+      <version>0.1</version>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+</project>

+ 35 - 0
src/main/lombok/org/leumasjaffe/observer/IndirectObservableListener.java

@@ -0,0 +1,35 @@
+package org.leumasjaffe.observer;
+
+import java.util.Objects;
+import java.util.function.BiConsumer;
+
+import lombok.experimental.FieldDefaults;
+import lombok.experimental.NonFinal;
+import lombok.AccessLevel;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+@FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
+@Getter(value=AccessLevel.PACKAGE)
+@RequiredArgsConstructor
+public class IndirectObservableListener<C, T> {
+	C component;
+	BiConsumer<? super C, ? super T> update;
+
+	@NonFinal T model = null;
+	
+	public void setObserved( T obs, Observable... extra ) {
+		Objects.requireNonNull( obs );
+		if ( obs == model ) return;
+		ObserverDispatch.unsubscribeAll( this );
+		model = obs;
+		updateComponent( );
+		for ( int i = 0; i < extra.length; ++i ) {
+			ObserverDispatch.subscribe( extra[i], this, () -> updateComponent( ) );
+		}
+	}
+
+	private void updateComponent() {
+		update.accept(component, model);
+	}
+}

+ 7 - 0
src/main/lombok/org/leumasjaffe/observer/Observable.java

@@ -0,0 +1,7 @@
+package org.leumasjaffe.observer;
+
+import java.util.UUID;
+
+public class Observable {
+	public final transient UUID observableId = UUID.randomUUID();
+}

+ 45 - 0
src/main/lombok/org/leumasjaffe/observer/ObservableController.java

@@ -0,0 +1,45 @@
+package org.leumasjaffe.observer;
+
+import java.util.Objects;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
+
+import javax.swing.text.JTextComponent;
+
+import org.leumasjaffe.event.AnyActionDocumentListener;
+import org.leumasjaffe.observer.helper.Helper;
+
+import lombok.experimental.FieldDefaults;
+import lombok.AccessLevel;
+
+@FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
+public class ObservableController<S extends JTextComponent, T extends Observable> extends ObservableListener<S, T> {
+	Helper<T> func;
+
+	public ObservableController(final S comp, final Helper<T> func,
+			final BiConsumer<? super S, ? super T> update) {
+		super(comp, update);
+		this.func = func;
+		AnyActionDocumentListener.skipEmpty(comp, evt -> accept( ) );
+	}
+	
+	public ObservableController(final S comp, final Helper<T> func,
+			final BiConsumer<? super S, ? super T> update, final Consumer<T> onEmpty) {
+		super(comp, update);
+		this.func = func;
+		AnyActionDocumentListener.emptyOrText( comp, 
+				e -> onEmpty.accept( impl.getModel() ), 
+				evt -> accept( ) );
+	}
+
+	private boolean update() {
+		return func.apply( impl.getComponent().getText( ), impl.getModel() );
+	}
+
+	private void accept() {
+		Objects.requireNonNull( impl.getModel() );
+		if ( update( ) ) {
+			ObserverDispatch.notifySubscribers( impl.getModel(), this );
+		}
+	}
+}

+ 19 - 0
src/main/lombok/org/leumasjaffe/observer/ObservableListener.java

@@ -0,0 +1,19 @@
+package org.leumasjaffe.observer;
+
+import java.util.function.BiConsumer;
+
+import lombok.AccessLevel;
+import lombok.experimental.FieldDefaults;
+
+@FieldDefaults(level=AccessLevel.PROTECTED, makeFinal=true)
+public class ObservableListener<C, T extends Observable> {
+	IndirectObservableListener<C, T> impl;
+	
+	public ObservableListener(final C comp, final BiConsumer<? super C, ? super T> func) {
+		impl = new IndirectObservableListener<>(comp, func);
+	}
+	
+	public void setObserved( T obs ) {
+		impl.setObserved(obs, obs);
+	}
+}

+ 39 - 0
src/main/lombok/org/leumasjaffe/observer/ObserverDispatch.java

@@ -0,0 +1,39 @@
+package org.leumasjaffe.observer;
+
+import java.lang.ref.WeakReference;
+import java.util.UUID;
+
+import com.google.common.collect.LinkedListMultimap;
+import com.google.common.collect.Multimap;
+
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.experimental.FieldDefaults;
+import lombok.experimental.UtilityClass;
+
+@UtilityClass
+@FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
+public class ObserverDispatch {
+	@AllArgsConstructor
+	@FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
+	private static class Pair {
+		WeakReference<Object> obj;
+		Subscriber sub;
+	}
+	
+	Multimap<UUID, Pair> observers = LinkedListMultimap.create();
+	
+	public void subscribe(Observable target, Object src, Subscriber sub) {
+		observers.put(target.observableId, new Pair(new WeakReference<>(src), sub));
+	}
+	
+	public void unsubscribeAll(Object src) {
+		if (src == null) return;
+		observers.entries().removeIf( e -> e.getValue().obj == src );
+	}
+	
+	public void notifySubscribers(Observable target, Object src) {
+		observers.get(target.observableId).stream().filter( p -> p.obj.get() != src ).forEach( 
+				p -> p.sub.notifyUpdate() );
+	}
+}

+ 6 - 0
src/main/lombok/org/leumasjaffe/observer/Subscriber.java

@@ -0,0 +1,6 @@
+package org.leumasjaffe.observer;
+
+@FunctionalInterface
+public interface Subscriber {
+	public void notifyUpdate();
+}

+ 10 - 0
src/main/lombok/org/leumasjaffe/observer/helper/Helper.java

@@ -0,0 +1,10 @@
+package org.leumasjaffe.observer.helper;
+
+import java.util.function.BiFunction;
+
+import org.leumasjaffe.observer.Observable;
+
+//  @FunctionalInterface
+  public interface Helper<T extends Observable> extends BiFunction<String, T, Boolean> {
+//    public boolean update( final String str, final T ref );
+  }