├── .gitattributes ├── .gitignore ├── 2017-april ├── event-driven-arch-pattern │ └── com │ │ └── alg │ │ └── ap │ │ ├── eventdriven2 │ │ ├── EventBus.java │ │ ├── ListenerMethod.java │ │ ├── ListenersRegistry.java │ │ ├── ReflectionUtil.java │ │ ├── Subscribe.java │ │ └── Subscriber1.java │ │ └── events │ │ ├── CircularShifter.java │ │ ├── Driver.java │ │ ├── Event.java │ │ ├── EventManager.java │ │ ├── EventQueue.java │ │ ├── IEventManager.java │ │ ├── InputReader.java │ │ ├── OutputWriter.java │ │ └── Sorter.java ├── main-subroutine-arch-pattern │ └── com │ │ └── alg │ │ └── ap │ │ └── procedural │ │ └── Driver.java ├── oo-arch-pattern │ └── com │ │ └── alg │ │ └── ap │ │ └── oostyle │ │ ├── CircularShifter.java │ │ ├── Driver.java │ │ ├── InputReader.java │ │ ├── OutputWriter.java │ │ └── Sorter.java └── pipe-filter-arch-pattern │ └── com │ └── alg │ └── ap │ └── pipefilter │ ├── CircularShifterFilter.java │ ├── Driver.java │ ├── Filter.java │ ├── InputReaderFilter.java │ ├── OutputWriterFilter.java │ └── SorterFilter.java ├── 2019-aug ├── 1.persistence pattern active record │ └── src │ │ └── com │ │ └── alg │ │ └── order │ │ ├── db │ │ └── Base.java │ │ ├── model │ │ ├── Ingredient.java │ │ ├── Item.java │ │ ├── Order.java │ │ └── Product.java │ │ └── ui │ │ ├── ContentPanel.java │ │ └── Test.java ├── 2.persistence pattern data access object │ └── src │ │ └── com │ │ └── alg │ │ └── order │ │ ├── db │ │ ├── AbstractDao.java │ │ ├── Entity.java │ │ ├── IDao.java │ │ ├── IngredientDao.java │ │ ├── OrderDao.java │ │ └── ProductDao.java │ │ ├── model │ │ ├── Ingredient.java │ │ ├── Item.java │ │ ├── Order.java │ │ └── Product.java │ │ └── ui │ │ ├── ContentPanel.java │ │ └── Test.java ├── 3.persistence pattern repository │ └── src │ │ └── com │ │ └── alg │ │ └── order │ │ ├── db │ │ ├── AbstractRepository.java │ │ ├── Entity.java │ │ ├── IRepository.java │ │ ├── IngredientRepository.java │ │ ├── OrderRepository.java │ │ ├── ProductRepository.java │ │ └── specifications │ │ │ ├── ISqlSpecification.java │ │ │ ├── ProductSpecificationByName.java │ │ │ └── ProductSpecificationByPriceRange.java │ │ ├── model │ │ ├── Ingredient.java │ │ ├── Item.java │ │ ├── Order.java │ │ └── Product.java │ │ └── ui │ │ ├── ContentPanel.java │ │ └── Test.java ├── 4.domain layer patterns │ └── src │ │ └── com │ │ └── alg │ │ └── order │ │ ├── common │ │ ├── AbstractId.java │ │ ├── AssertionConcern.java │ │ ├── Entity.java │ │ └── ValueObject.java │ │ ├── model │ │ ├── EmailAddress.java │ │ ├── Ingredient.java │ │ ├── IngredientColor.java │ │ ├── IngredientId.java │ │ ├── IngredientPrice.java │ │ ├── Order.java │ │ ├── OrderId.java │ │ ├── PostalAddress.java │ │ ├── Product.java │ │ ├── ProductId.java │ │ ├── ProductPrice.java │ │ └── Telephone.java │ │ ├── repository │ │ ├── AbstractRepository.java │ │ ├── IRepository.java │ │ ├── IngredientRepository.java │ │ ├── OrderRepository.java │ │ ├── ProductRepository.java │ │ └── specifications │ │ │ ├── ISqlSpecification.java │ │ │ ├── IngredeintSpecificationById.java │ │ │ ├── OrderSpecificationById.java │ │ │ ├── ProductSpecificationById.java │ │ │ ├── ProductSpecificationByName.java │ │ │ └── ProductSpecificationByPriceRange.java │ │ ├── service │ │ ├── IOrderService.java │ │ ├── IngredientDTO.java │ │ ├── OrderDTO.java │ │ ├── OrderServiceImpl.java │ │ ├── OrderSummaryDTO.java │ │ └── ProductDTO.java │ │ └── ui │ │ ├── ContentPanel.java │ │ └── Test.java ├── concurrency and parallel patterns │ ├── 1.synchronization problems │ │ └── src │ │ │ └── threading │ │ │ ├── Memory.java │ │ │ ├── RaceCondition.java │ │ │ ├── RaceConditionSol1.java │ │ │ └── Test.java │ ├── 2.wiki-wordcount │ │ └── src │ │ │ └── com │ │ │ └── alg │ │ │ └── concurrency │ │ │ └── threading │ │ │ ├── wordcount1 │ │ │ └── sequential │ │ │ │ ├── Page.java │ │ │ │ ├── Pages.java │ │ │ │ ├── Test.java │ │ │ │ └── Words.java │ │ │ ├── wordcount2 │ │ │ └── concurrent │ │ │ │ ├── Page.java │ │ │ │ ├── Pages.java │ │ │ │ ├── Parser.java │ │ │ │ ├── Test.java │ │ │ │ ├── WordCounter.java │ │ │ │ └── Words.java │ │ │ ├── wordcount3 │ │ │ └── concurrent │ │ │ │ ├── Page.java │ │ │ │ ├── Pages.java │ │ │ │ ├── Parser.java │ │ │ │ ├── Test.java │ │ │ │ ├── WordCounter.java │ │ │ │ └── Words.java │ │ │ └── wordcount4 │ │ │ └── concurrent │ │ │ ├── Page.java │ │ │ ├── Pages.java │ │ │ ├── Parser.java │ │ │ ├── Test.java │ │ │ ├── WordCounter.java │ │ │ └── Words.java │ └── 3.webserver │ │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── alg │ │ │ ├── common │ │ │ └── app │ │ │ │ ├── domain │ │ │ │ ├── Command.java │ │ │ │ ├── Constants.java │ │ │ │ ├── ErrorCommand.java │ │ │ │ ├── QueryCommand.java │ │ │ │ ├── ReportCommand.java │ │ │ │ ├── StopCommand.java │ │ │ │ ├── WDI.java │ │ │ │ ├── WDILoader.java │ │ │ │ └── WDIService.java │ │ │ │ └── repository │ │ │ │ └── IWDIRepository.java │ │ │ └── webserver │ │ │ ├── benchmark │ │ │ └── MyBenchmark.java │ │ │ ├── client │ │ │ ├── ConcurrentClients.java │ │ │ └── SerialClient.java │ │ │ ├── concurrent │ │ │ ├── threadperconnection │ │ │ │ ├── EventHandler.java │ │ │ │ └── WebServer.java │ │ │ └── threadpool │ │ │ │ ├── EventHandler.java │ │ │ │ └── WebServer.java │ │ │ └── serial │ │ │ ├── EventHandler.java │ │ │ └── WebServer.java │ │ └── resources │ │ └── application.properties └── db-script.sql ├── event-driven-arch-pattern └── com │ └── alg │ └── ap │ ├── eventdriven2 │ ├── EventBus.java │ ├── ListenerMethod.java │ ├── ListenersRegistry.java │ ├── ReflectionUtil.java │ ├── Subscribe.java │ └── Subscriber1.java │ └── events │ ├── CircularShifter.java │ ├── Driver.java │ ├── Event.java │ ├── EventManager.java │ ├── EventQueue.java │ ├── IEventManager.java │ ├── InputReader.java │ ├── OutputWriter.java │ └── Sorter.java ├── main-subroutine-arch-pattern └── com │ └── alg │ └── ap │ └── procedural │ └── Driver.java ├── oo-arch-pattern └── com │ └── alg │ └── ap │ └── oostyle │ ├── CircularShifter.java │ ├── Driver.java │ ├── InputReader.java │ ├── OutputWriter.java │ └── Sorter.java └── pipe-filter-arch-pattern └── com └── alg └── ap └── pipefilter ├── CircularShifterFilter.java ├── Driver.java ├── Filter.java ├── InputReaderFilter.java ├── OutputWriterFilter.java └── SorterFilter.java /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /2017-april/event-driven-arch-pattern/com/alg/ap/eventdriven2/EventBus.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.eventdriven2; 2 | 3 | import java.util.List; 4 | 5 | public class EventBus { 6 | private ListenersRegistry listenersRegistry; 7 | private String tag = ""; 8 | 9 | public EventBus(String tag) { 10 | listenersRegistry = new ListenersRegistry(); 11 | this.tag = tag; 12 | } 13 | 14 | /** 15 | * Registers an event listener to the event bus 16 | */ 17 | public void register(Object listener) { 18 | if (listener == null) { 19 | System.out.println("Null object can not be registered."); 20 | } else { 21 | System.out.println("Registering listener " + listener); 22 | listenersRegistry.register(listener); 23 | } 24 | } 25 | 26 | /** 27 | * De-registers a listener object that has been registered with the event bus. 28 | * After de-registration, the object cease to listen to any further event. 29 | * */ 30 | public void deregister(Object listener) { 31 | if (listener == null) { 32 | System.out.println("Null object can not be de-registered."); 33 | } else { 34 | System.out.println("Un-Registering listener " + listener); 35 | listenersRegistry.deregister(listener); 36 | } 37 | } 38 | 39 | /** 40 | * Posts an event to the event bus. 41 | * */ 42 | public void post(Object event) throws Exception { 43 | if (event == null) { 44 | System.out.println("Null event can not be posted."); 45 | return; 46 | } 47 | System.out.println("Event " + event + " has been posted to the bus " + tag); 48 | 49 | List subscribers = listenersRegistry.getSubscribers(event); 50 | if (subscribers != null && !subscribers.isEmpty()) { 51 | System.out.println("Total subscribers found for event " + event + " is = " + subscribers.size()); 52 | System.out.println("Dispatching event " + event); 53 | for(ListenerMethod listenerMethod: subscribers) { 54 | listenerMethod.method.invoke(listenerMethod.target, event); 55 | } 56 | } 57 | } 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /2017-april/event-driven-arch-pattern/com/alg/ap/eventdriven2/ListenerMethod.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.eventdriven2; 2 | 3 | import java.lang.reflect.Method; 4 | import java.lang.reflect.Modifier; 5 | 6 | 7 | public class ListenerMethod { 8 | Object target; 9 | Method method; 10 | Class eventType; 11 | 12 | 13 | ListenerMethod(Method method, Class eventType) { 14 | this.method = method; 15 | this.eventType = eventType; 16 | } 17 | 18 | /* @Override 19 | public boolean equals(Object obj) { 20 | if (this == obj) 21 | return true; 22 | if (obj == null) 23 | return false; 24 | if (getClass() != obj.getClass()) 25 | return false; 26 | ListenerMethod other = (ListenerMethod) obj; 27 | 28 | return other.method.getName().equals(method.getName()) 29 | && other.method.getModifiers() != Modifier.PRIVATE 30 | && method.getModifiers() != Modifier.PRIVATE 31 | && eventType.equals(other.eventType) 32 | && target != null 33 | && other.target != null 34 | && target.equals(other.target); 35 | } 36 | 37 | @Override 38 | public int hashCode() { 39 | return new HashCodeBuilder() 40 | .append(method) 41 | .append(target) 42 | .append(eventType) 43 | .toHashCode(); 44 | return 10; 45 | }*/ 46 | 47 | @Override 48 | public String toString() { 49 | return "[" + 50 | "method = " + 51 | method.getName() + 52 | ", target = " + 53 | target + 54 | ", event = " + 55 | eventType.getName() + 56 | "]"; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /2017-april/event-driven-arch-pattern/com/alg/ap/eventdriven2/ListenersRegistry.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.eventdriven2; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | import java.util.concurrent.ConcurrentHashMap; 6 | import java.util.concurrent.CopyOnWriteArrayList; 7 | 8 | public class ListenersRegistry { 9 | // keep track of event and its registered subscribed methods 10 | private Map, List> registry = 11 | new ConcurrentHashMap, List>(); 12 | // cache to keep track of all listener object 13 | private List subscriberCache = new CopyOnWriteArrayList(); 14 | 15 | 16 | void register(Object listener) { 17 | if (subscriberCache.contains(listener)) { 18 | System.out.println(listener + " has already been registered."); 19 | } 20 | subscriberCache.add(listener); 21 | 22 | // extract all subscribed methods from the listener and its super class and interfaces. 23 | List subscribedMethods = ReflectionUtil.findSubscribedMethods(listener.getClass()); 24 | if (subscribedMethods == null || subscribedMethods.isEmpty()) { 25 | System.out.println(listener + " does not have any method marked with @Subscribe."); 26 | } 27 | 28 | for (ListenerMethod listenerMethod : subscribedMethods) { 29 | listenerMethod.target = listener; 30 | Class eventType = listenerMethod.eventType; 31 | if (registry.containsKey(eventType)) { 32 | List listenerMethods = registry.get(eventType); 33 | 34 | // check ListenerMethod's equals method 35 | if (!listenerMethods.contains(listenerMethod)) { 36 | listenerMethods.add(listenerMethod); 37 | System.out.println(listenerMethod + " has been registered."); 38 | } else { 39 | System.out.println(listenerMethod + " has already been registered."); 40 | } 41 | } else { 42 | List listenerMethods = new CopyOnWriteArrayList(); 43 | listenerMethods.add(listenerMethod); 44 | registry.put(listenerMethod.eventType, listenerMethods); 45 | System.out.println(listenerMethod + " has been registered."); 46 | } 47 | } 48 | } 49 | 50 | /** 51 | * De-registers a listener object. 52 | * */ 53 | void deregister(Object listener) { 54 | for (Object object : subscriberCache) { 55 | if (object.equals(listener)) { 56 | // found in strong cache, remove it break 57 | if (subscriberCache.remove(listener)) { 58 | System.out.println(listener + " removed from the subscriber cache."); 59 | } 60 | break; 61 | } 62 | } 63 | 64 | // iterate the whole registry map 65 | for (Map.Entry, List> entry : registry.entrySet()) { 66 | List subscribedMethods = entry.getValue(); 67 | for (ListenerMethod listenerMethod : subscribedMethods) { 68 | if (listenerMethod.target.equals(listener)) { 69 | if (subscribedMethods.remove(listenerMethod)) { 70 | System.out.println(listenerMethod + " has been un-registered."); 71 | } 72 | } 73 | } 74 | } 75 | 76 | } 77 | 78 | /** 79 | * Get all registered subscriber information for an event. 80 | * */ 81 | List getSubscribers(Object event) { 82 | if (event != null) { 83 | Class eventType = event.getClass(); 84 | // loop through the registry to get all subscribed method 85 | if (registry.containsKey(eventType)) { 86 | return registry.get(eventType); 87 | } 88 | } 89 | return null; 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /2017-april/event-driven-arch-pattern/com/alg/ap/eventdriven2/ReflectionUtil.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.eventdriven2; 2 | 3 | 4 | import java.lang.reflect.Method; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * A reflection utility class to extract information about subscriber methods 10 | * from a registering listener object. 11 | */ 12 | class ReflectionUtil { 13 | /** 14 | * Finds all subscriber methods in the whole class hierarchy of {@code subscribedClass}. 15 | * 16 | * */ 17 | static List findSubscribedMethods(Class subscribedClass) { 18 | List listenerMethodList = new ArrayList(); 19 | if (subscribedClass != null) { 20 | Method[] declaredMethods = subscribedClass.getDeclaredMethods(); 21 | for (Method method : declaredMethods) { 22 | if (method.isAnnotationPresent(Subscribe.class) && !method.isBridge() && !method.isSynthetic()) { 23 | if (method.getParameterTypes().length != 1) { 24 | System.out.println(method.getName() + " has @Subscribe annotation, " + 25 | "but it should have exactly 1 parameter."); 26 | } 27 | 28 | Class parameterType = method.getParameterTypes()[0]; 29 | if (parameterType.isArray() || method.isVarArgs()) { 30 | System.out.println(method.getName() + " has @Subscribe annotation, " + 31 | "but its parameter should not be an array or varargs."); 32 | } 33 | 34 | method.setAccessible(true); 35 | ListenerMethod listenerMethod = new ListenerMethod(method, method.getParameterTypes()[0]); 36 | listenerMethodList.add(listenerMethod); 37 | } 38 | } 39 | 40 | if (subscribedClass.getSuperclass() != null && !subscribedClass.getSuperclass().equals(Object.class)) { 41 | List subscribedMethods = findSubscribedMethods(subscribedClass.getSuperclass()); 42 | listenerMethodList.addAll(subscribedMethods); 43 | } 44 | 45 | if (subscribedClass.getInterfaces() != null && subscribedClass.getInterfaces().length > 0) { 46 | for (Class interfaceClass : subscribedClass.getInterfaces()) { 47 | List subscribedMethods = findSubscribedMethods(interfaceClass); 48 | listenerMethodList.addAll(subscribedMethods); 49 | } 50 | } 51 | } 52 | return listenerMethodList; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /2017-april/event-driven-arch-pattern/com/alg/ap/eventdriven2/Subscribe.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.eventdriven2; 2 | 3 | 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | /** 10 | * Makes a method eligible to respond to an event. 11 | * 12 | * It should be applied to a method (with any access modifier) which has 13 | * only one argument with the type of the event. If it is applied on a method 14 | * having no parameter or more than one parameters, during registration,an exception will be thrown 15 | * 16 | * If a method in an interface or an abstract class is marked with this annotation, 17 | * all the overridden methods will be eligible for subscription. 18 | */ 19 | @Retention(RetentionPolicy.RUNTIME) 20 | @Target({ElementType.METHOD}) 21 | public @interface Subscribe { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /2017-april/event-driven-arch-pattern/com/alg/ap/eventdriven2/Subscriber1.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.eventdriven2; 2 | 3 | public class Subscriber1 { 4 | private EventBus eventBus; 5 | 6 | public Subscriber1(EventBus eventBus) { 7 | super(); 8 | this.eventBus = eventBus; 9 | eventBus.register(this); 10 | } 11 | 12 | public void push() throws Exception { 13 | eventBus.post(""); 14 | } 15 | 16 | @Subscribe 17 | public void receive(String event) { 18 | 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /2017-april/event-driven-arch-pattern/com/alg/ap/events/CircularShifter.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | package com.alg.ap.events; 4 | 5 | public class CircularShifter extends Thread { 6 | private EventManager eventManager; 7 | private String id; 8 | 9 | public CircularShifter(EventManager eventManager, String id) { 10 | super(); 11 | this.eventManager = eventManager; 12 | eventManager.register(id); 13 | this.id = id; 14 | } 15 | 16 | public void run() { 17 | while (true) { 18 | Event event = eventManager.getEvent(id); 19 | System.out.println("shifter received event" + event); 20 | if (event == null) { 21 | try { 22 | Thread.sleep(1000); 23 | } catch (Exception e) { 24 | } 25 | continue; 26 | } 27 | if (event.getId() == -1) { 28 | event.setSourceid(id); 29 | eventManager.postEvent(event); 30 | break; 31 | } 32 | String line = event.getMessage(); 33 | int nshifts = line.split(" ").length; 34 | for (int i = 0; i < nshifts; ++i) { 35 | Event shift_event = new Event(); 36 | int pos = line.indexOf(' '); 37 | String current = line.substring(0, pos); 38 | String tmp = line.substring(pos + 1) + " " + current; 39 | shift_event.setId(i); 40 | shift_event.setMessage(tmp); 41 | shift_event.setSourceid(id); 42 | eventManager.postEvent(shift_event); 43 | System.out.println("Shifter is posting event:" + shift_event); 44 | line = tmp; 45 | } 46 | } 47 | 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /2017-april/event-driven-arch-pattern/com/alg/ap/events/Driver.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.events; 2 | 3 | public class Driver { 4 | 5 | public static void main(String[] args) { 6 | EventManager eventManager = new EventManager(); 7 | InputReader ir = new InputReader(eventManager, args[0], "ir"); 8 | CircularShifter shifter = new CircularShifter(eventManager, "cs"); 9 | Sorter sorter = new Sorter(eventManager, "sorter"); 10 | OutputWriter ow = new OutputWriter(eventManager, args[1],"ow"); 11 | ir.start(); 12 | shifter.start(); 13 | sorter.start(); 14 | ow.start(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /2017-april/event-driven-arch-pattern/com/alg/ap/events/Event.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.events; 2 | 3 | public class Event { 4 | private int id; 5 | private String sourceid; 6 | private String message; 7 | 8 | public Event() { 9 | super(); 10 | // TODO Auto-generated constructor stub 11 | } 12 | 13 | public Event(int id, String sourceid, String message) { 14 | super(); 15 | this.id = id; 16 | this.sourceid = sourceid; 17 | this.message = message; 18 | } 19 | 20 | public int getId() { 21 | return id; 22 | } 23 | 24 | public String getSourceid() { 25 | return sourceid; 26 | } 27 | 28 | public String getMessage() { 29 | return message; 30 | } 31 | 32 | public void setId(int id) { 33 | this.id = id; 34 | } 35 | 36 | public void setSourceid(String sourceid) { 37 | this.sourceid = sourceid; 38 | } 39 | 40 | public void setMessage(String message) { 41 | this.message = message; 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return "Event [id=" + id + ", sourceid=" + sourceid + ", message=" 47 | + message + "]"; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /2017-april/event-driven-arch-pattern/com/alg/ap/events/EventManager.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.events; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import java.util.Map.Entry; 6 | 7 | public class EventManager implements IEventManager { 8 | private Map event_queues; 9 | 10 | public EventManager() { 11 | event_queues = new HashMap(); 12 | } 13 | 14 | @Override 15 | public synchronized void register(String name) { 16 | event_queues.put(name, new EventQueue(name)); 17 | } 18 | 19 | @Override 20 | public synchronized void unregister(String id) { 21 | for(String eq:event_queues.keySet()) { 22 | if(eq.equals(id)) 23 | event_queues.remove(eq); 24 | } 25 | } 26 | 27 | @Override 28 | public synchronized void postEvent(Event event) { 29 | for(Entry entry:event_queues.entrySet()) { 30 | if(entry.getKey().equals(event.getSourceid())) 31 | entry.getValue().addEvent(event); 32 | } 33 | 34 | } 35 | 36 | @Override 37 | public Event getEvent(String id) { 38 | if(id.equals("cs")) 39 | id = "ir"; 40 | else if(id.equals("sorter")) 41 | id = "cs"; 42 | else if(id.equals(("ow"))) 43 | id = "sorter"; 44 | return event_queues.get(id).fetchEvent(); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /2017-april/event-driven-arch-pattern/com/alg/ap/events/EventQueue.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.events; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class EventQueue { 7 | private String id; 8 | private List events; 9 | 10 | public EventQueue(String id) { 11 | this.id = id; 12 | events = new ArrayList(); 13 | } 14 | 15 | public String getId() { 16 | return id; 17 | } 18 | 19 | public void addEvent(Event e) { 20 | events.add(e); 21 | } 22 | 23 | public Event fetchEvent() { 24 | if(events.size() == 0) return null; 25 | return events.remove(0); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /2017-april/event-driven-arch-pattern/com/alg/ap/events/IEventManager.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.events; 2 | 3 | public interface IEventManager { 4 | void register(String id); 5 | void unregister(String id); 6 | void postEvent(Event event); 7 | Event getEvent(String id); 8 | } 9 | -------------------------------------------------------------------------------- /2017-april/event-driven-arch-pattern/com/alg/ap/events/InputReader.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.events; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.FileReader; 5 | 6 | public class InputReader extends Thread { 7 | private EventManager eventManager; 8 | private String infile; 9 | private String id; 10 | 11 | public InputReader(EventManager eventManager, String infile, String id) { 12 | this.eventManager = eventManager; 13 | eventManager.register(id); 14 | this.id = id; 15 | this.infile = infile; 16 | } 17 | 18 | public void run() { 19 | try { 20 | BufferedReader br = new BufferedReader(new FileReader(infile)); 21 | String line; 22 | int count = 0; 23 | while ((line = br.readLine()) != null) { 24 | Event event = new Event(++count, id, line); 25 | System.out.println("Input reader is posting event:" + event); 26 | eventManager.postEvent(event); 27 | } 28 | Event event = new Event(-1,id, null); 29 | eventManager.postEvent(event); 30 | System.out.println("Input reader is posting event:" + event); 31 | } catch (Exception e) { 32 | System.out.println(e); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /2017-april/event-driven-arch-pattern/com/alg/ap/events/OutputWriter.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.events; 2 | 3 | import java.io.BufferedWriter; 4 | import java.io.FileWriter; 5 | 6 | public class OutputWriter extends Thread { 7 | private EventManager eventManager; 8 | private String outfile; 9 | private String id; 10 | 11 | public OutputWriter(EventManager eventManager, String outfile, String id) { 12 | this.eventManager = eventManager; 13 | eventManager.register(id); 14 | this.id = id; 15 | this.outfile = outfile; 16 | } 17 | 18 | public void run() { 19 | try { 20 | BufferedWriter bw = new BufferedWriter(new FileWriter(outfile)); 21 | while (true) { 22 | Event event = eventManager.getEvent(id); 23 | System.out.println("Output writer receiving event:" + event); 24 | if (event == null) { 25 | try { 26 | Thread.sleep(1000); 27 | } catch (Exception e) { 28 | } 29 | continue; 30 | } 31 | if (event.getId() == -1) { 32 | bw.close(); 33 | break; 34 | } 35 | bw.write(event.getMessage()); 36 | bw.newLine(); 37 | } 38 | } catch (Exception e) { 39 | System.out.println(e); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /2017-april/event-driven-arch-pattern/com/alg/ap/events/Sorter.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.events; 2 | 3 | import java.util.TreeSet; 4 | 5 | public class Sorter extends Thread { 6 | private TreeSet sorted_lines; 7 | private EventManager eventManager; 8 | private String id; 9 | 10 | public Sorter(EventManager eventManager, String id) { 11 | sorted_lines = new TreeSet(); 12 | this.eventManager = eventManager; 13 | this.id = id; 14 | eventManager.register(id); 15 | } 16 | 17 | public void run() { 18 | int count = 0; 19 | while (true) { 20 | Event event = eventManager.getEvent(id); 21 | System.out.println("Sorter receiving event:" + event); 22 | if(event == null) { 23 | try { 24 | Thread.sleep(1000); 25 | } catch (Exception e) { 26 | } 27 | continue; 28 | } 29 | if (event.getId() == -1) { 30 | for (String tmp : sorted_lines) { 31 | Event event2 = new Event(++count, id, tmp); 32 | eventManager.postEvent(event2); 33 | System.out.println("Sorter posting event:" + event2); 34 | } 35 | event.setSourceid(id); 36 | eventManager.postEvent(event); 37 | System.out.println("Sorter posting event:" + event); 38 | break; 39 | } 40 | sorted_lines.add(event.getMessage()); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /2017-april/main-subroutine-arch-pattern/com/alg/ap/procedural/Driver.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.procedural; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.BufferedWriter; 5 | import java.io.FileReader; 6 | import java.io.FileWriter; 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.List; 10 | 11 | public class Driver { 12 | static List lines = new ArrayList(); 13 | static List shifted_lines = new ArrayList(); 14 | 15 | public static void readInput(String infile) throws Exception { 16 | BufferedReader br = new BufferedReader(new BufferedReader( 17 | new FileReader(infile))); 18 | String line; 19 | while ((line = br.readLine()) != null) 20 | lines.add(line); 21 | br.close(); 22 | } 23 | 24 | public static void circularShift() { 25 | for (String line : lines) { 26 | int nshifts = line.split(" ").length; 27 | for (int i = 0; i < nshifts; ++i) { 28 | int pos = line.indexOf(' '); 29 | String current = line.substring(0, pos); 30 | String tmp = line.substring(pos+1) + " " + current; 31 | shifted_lines.add(tmp); 32 | line = tmp; 33 | } 34 | } 35 | } 36 | 37 | public static void sort() { 38 | Collections.sort(shifted_lines); 39 | } 40 | 41 | public static void writeOutput(String outfile) throws Exception { 42 | BufferedWriter bw = new BufferedWriter(new FileWriter(outfile)); 43 | for(String line: shifted_lines) { 44 | bw.write(line); 45 | bw.newLine(); 46 | } 47 | bw.close(); 48 | } 49 | 50 | public static void main(String[] args) throws Exception { 51 | readInput(args[0]); 52 | System.out.println(lines); 53 | circularShift(); 54 | System.out.println(shifted_lines); 55 | sort(); 56 | System.out.println(shifted_lines); 57 | writeOutput(args[1]); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /2017-april/oo-arch-pattern/com/alg/ap/oostyle/CircularShifter.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.oostyle; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class CircularShifter { 7 | List shifted_lines = new ArrayList(); 8 | 9 | public void circularShift(List lines) { 10 | for (String line : lines) { 11 | int nshifts = line.split(" ").length; 12 | for (int i = 0; i < nshifts; ++i) { 13 | int pos = line.indexOf(' '); 14 | String current = line.substring(0, pos); 15 | String tmp = line.substring(pos+1) + " " + current; 16 | shifted_lines.add(tmp); 17 | line = tmp; 18 | } 19 | } 20 | } 21 | 22 | public List getShiftedLines() { 23 | return shifted_lines; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /2017-april/oo-arch-pattern/com/alg/ap/oostyle/Driver.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.oostyle; 2 | 3 | public class Driver { 4 | 5 | public static void main(String[] args) throws Exception { 6 | InputReader ir = new InputReader(); 7 | ir.readInput(args[0]); 8 | CircularShifter shifter = new CircularShifter(); 9 | shifter.circularShift(ir.getLines()); 10 | Sorter sorter = new Sorter(); 11 | sorter.sort(shifter.getShiftedLines()); 12 | OutputWriter ow = new OutputWriter(); 13 | ow.writeOuput(sorter.getSortedShiftedLines(), args[1]); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /2017-april/oo-arch-pattern/com/alg/ap/oostyle/InputReader.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.oostyle; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.FileReader; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class InputReader { 9 | private List lines = new ArrayList(); 10 | 11 | public void readInput(String infile) throws Exception { 12 | BufferedReader br = new BufferedReader(new BufferedReader( 13 | new FileReader(infile))); 14 | String line; 15 | while ((line = br.readLine()) != null) 16 | lines.add(line); 17 | br.close(); 18 | } 19 | 20 | //TODO: replace it with iterator pattern 21 | public List getLines() { 22 | return lines; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /2017-april/oo-arch-pattern/com/alg/ap/oostyle/OutputWriter.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.oostyle; 2 | 3 | import java.io.BufferedWriter; 4 | import java.io.FileWriter; 5 | import java.util.List; 6 | 7 | public class OutputWriter { 8 | 9 | public void writeOuput(List sorted_shifted_lines, String outfile) 10 | throws Exception { 11 | BufferedWriter bw = new BufferedWriter(new FileWriter(outfile)); 12 | for (String line : sorted_shifted_lines) { 13 | bw.write(line); 14 | bw.newLine(); 15 | } 16 | bw.close(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /2017-april/oo-arch-pattern/com/alg/ap/oostyle/Sorter.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.oostyle; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | 7 | public class Sorter { 8 | private List sorted_shifted_lines; 9 | 10 | public void sort(List shifted_lines) { 11 | sorted_shifted_lines = new ArrayList(shifted_lines); 12 | Collections.sort(sorted_shifted_lines); 13 | } 14 | 15 | public List getSortedShiftedLines() { 16 | return sorted_shifted_lines; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /2017-april/pipe-filter-arch-pattern/com/alg/ap/pipefilter/CircularShifterFilter.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.pipefilter; 2 | 3 | import java.io.DataInputStream; 4 | import java.io.PrintStream; 5 | 6 | public class CircularShifterFilter extends Filter { 7 | 8 | public void run() { 9 | try { 10 | PrintStream ps = new PrintStream(getOutputWriterPort()); 11 | DataInputStream dis = new DataInputStream(getInputReadPort()); 12 | String line; 13 | System.out.println("Circular Shifter Filter Started"); 14 | while((line = dis.readLine()) != null) { 15 | int nshifts = line.split(" ").length; 16 | for (int i = 0; i < nshifts; ++i) { 17 | int pos = line.indexOf(' '); 18 | String current = line.substring(0, pos); 19 | String tmp = line.substring(pos + 1) + " " + current; 20 | ps.println(tmp); 21 | System.out.println("Circular Shifter Filter:" + tmp); 22 | line = tmp; 23 | } 24 | } 25 | closePorts(); 26 | ps.close(); 27 | dis.close(); 28 | } catch (Exception e) { 29 | System.out.println(e); 30 | closePorts(); 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /2017-april/pipe-filter-arch-pattern/com/alg/ap/pipefilter/Driver.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.pipefilter; 2 | 3 | public class Driver { 4 | public static void main( String[] args) { 5 | InputReaderFilter irfilter = new InputReaderFilter(args[0]); 6 | CircularShifterFilter csfilter = new CircularShifterFilter(); 7 | SorterFilter sortfilter = new SorterFilter(); 8 | OutputWriterFilter owfilter = new OutputWriterFilter(args[1]); 9 | 10 | owfilter.connect(sortfilter); 11 | sortfilter.connect(csfilter); 12 | csfilter.connect(irfilter); 13 | 14 | irfilter.start(); 15 | csfilter.start(); 16 | sortfilter.start(); 17 | owfilter.start(); 18 | } 19 | } -------------------------------------------------------------------------------- /2017-april/pipe-filter-arch-pattern/com/alg/ap/pipefilter/Filter.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.pipefilter; 2 | 3 | import java.io.*; 4 | 5 | public class Filter extends Thread { 6 | private PipedInputStream inputReadPort = new PipedInputStream(); 7 | private PipedOutputStream outputWritePort = new PipedOutputStream(); 8 | //private Filter inputFilter; 9 | 10 | public void connect(Filter filter) { 11 | try { 12 | inputReadPort.connect( filter.getOutputWriterPort() ); 13 | //inputFilter = Filter; 14 | 15 | } catch(Exception e ) { 16 | System.out.println(e); 17 | 18 | } 19 | 20 | } 21 | 22 | public void closePorts() { 23 | try { 24 | inputReadPort.close(); 25 | outputWritePort.close(); 26 | } catch( Exception e ) { 27 | System.out.println(e); 28 | } 29 | 30 | } 31 | 32 | public PipedInputStream getInputReadPort() { 33 | return inputReadPort; 34 | } 35 | 36 | public PipedOutputStream getOutputWriterPort() { 37 | return outputWritePort; 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /2017-april/pipe-filter-arch-pattern/com/alg/ap/pipefilter/InputReaderFilter.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.pipefilter; 2 | 3 | import java.io.*; 4 | 5 | public class InputReaderFilter extends Filter { 6 | private String infile; 7 | 8 | public InputReaderFilter(String infile) { 9 | this.infile = infile; 10 | } 11 | 12 | public void run() { 13 | try { 14 | BufferedReader br = new BufferedReader(new BufferedReader( 15 | new FileReader(infile))); 16 | String line; 17 | PrintStream ps = new PrintStream(getOutputWriterPort()); 18 | System.out.println("Input Reader filter started"); 19 | while ((line = br.readLine()) != null) { 20 | System.out.println("Input reader Filter: " + line); 21 | ps.println(line); 22 | //ps.flush(); 23 | } 24 | closePorts(); 25 | br.close(); 26 | ps.close(); 27 | } catch (Exception e) { 28 | System.out.println(e); 29 | closePorts(); 30 | } 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /2017-april/pipe-filter-arch-pattern/com/alg/ap/pipefilter/OutputWriterFilter.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.pipefilter; 2 | 3 | import java.io.BufferedWriter; 4 | import java.io.DataInputStream; 5 | import java.io.FileWriter; 6 | 7 | public class OutputWriterFilter extends Filter { 8 | private String outfile; 9 | 10 | public OutputWriterFilter(String outfile) { 11 | this.outfile = outfile; 12 | } 13 | 14 | public void run() { 15 | try { 16 | BufferedWriter bw = new BufferedWriter(new FileWriter(outfile)); 17 | DataInputStream dis = new DataInputStream(getInputReadPort()); 18 | String line; 19 | System.out.println("Output writer filter started"); 20 | while((line = dis.readLine()) != null) { 21 | System.out.println("Output writer filter:" + line); 22 | bw.write(line); 23 | bw.newLine(); 24 | } 25 | closePorts(); 26 | bw.close(); 27 | dis.close(); 28 | } catch (Exception e) { 29 | System.out.println(e); 30 | closePorts(); 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /2017-april/pipe-filter-arch-pattern/com/alg/ap/pipefilter/SorterFilter.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.pipefilter; 2 | 3 | import java.io.DataInputStream; 4 | import java.io.PrintStream; 5 | import java.util.TreeSet; 6 | 7 | public class SorterFilter extends Filter { 8 | private TreeSet sorted_lines = new TreeSet(); 9 | 10 | public void run() { 11 | try { 12 | PrintStream ps = new PrintStream(getOutputWriterPort()); 13 | DataInputStream dis = new DataInputStream(getInputReadPort()); 14 | String line; 15 | System.out.println("Sorter Filter started"); 16 | while((line = dis.readLine()) != null) { 17 | System.out.println("Sorter Filter:" + line); 18 | sorted_lines.add(line); 19 | } 20 | for(String line1: sorted_lines) 21 | ps.println(line1); 22 | closePorts(); 23 | ps.close(); 24 | dis.close(); 25 | } catch (Exception e) { 26 | System.out.println(e); 27 | closePorts(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /2019-aug/1.persistence pattern active record/src/com/alg/order/db/Base.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.db; 2 | 3 | import java.sql.*; 4 | import java.util.Properties; 5 | 6 | public class Base { 7 | protected Connection connection; 8 | 9 | public Base() { 10 | 11 | } 12 | 13 | protected void connect() throws SQLException { 14 | String url = "jdbc:mysql://localhost:3306/test"; 15 | String user = "algo"; 16 | String password = "algo"; 17 | // Load the Oracle JDBC driver 18 | try { 19 | Class.forName("com.mysql.jdbc.Driver"); 20 | } catch (ClassNotFoundException e) { 21 | e.printStackTrace(); 22 | } 23 | 24 | Properties properties = new Properties(); 25 | properties.setProperty("user", user); 26 | properties.setProperty("password", password); 27 | properties.setProperty("useSSL", "false"); 28 | properties.setProperty("autoReconnect", "true"); 29 | 30 | // Connect to the database 31 | connection = DriverManager.getConnection(url, properties); 32 | } 33 | 34 | public Statement getStatement() throws SQLException { 35 | if (connection == null) 36 | connect(); 37 | return connection.createStatement(); 38 | } 39 | 40 | public String test() throws SQLException { 41 | 42 | Statement stmt = getStatement(); 43 | ResultSet rset = stmt.executeQuery("select SYSDATE from dual"); 44 | 45 | String result = ""; 46 | // Print the result 47 | while (rset.next()) 48 | result = rset.getString(1); 49 | 50 | // Close the RseultSet 51 | rset.close(); 52 | 53 | // Close the Statement 54 | stmt.close(); 55 | 56 | close(); 57 | return result; 58 | } 59 | 60 | private void close() throws SQLException { 61 | connection.close(); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /2019-aug/1.persistence pattern active record/src/com/alg/order/model/Ingredient.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | import java.sql.PreparedStatement; 4 | import java.sql.ResultSet; 5 | import java.sql.SQLException; 6 | import java.util.ArrayList; 7 | 8 | import com.alg.order.db.Base; 9 | 10 | public class Ingredient extends Base implements Item { 11 | private Integer id; 12 | private String name; 13 | private Float price; 14 | private String color; 15 | 16 | public Ingredient() { 17 | 18 | } 19 | public Ingredient(Integer id, String name, Float price, String color) { 20 | super(); 21 | this.id = id; 22 | this.name = name; 23 | this.price = price; 24 | this.color = color; 25 | } 26 | 27 | public void find(Integer id) throws SQLException { 28 | this.connect(); 29 | PreparedStatement pstmt = connection 30 | .prepareStatement("SELECT * FROM INGREDIENTS WHERE INGREDIENT_ID = ? "); 31 | pstmt.setInt(1, this.id); 32 | ResultSet rs = pstmt.executeQuery(); 33 | while (rs.next()) { 34 | this.name = rs.getString("INGREDIENT_NAME"); 35 | this.price = rs.getFloat("PRICE"); 36 | this.color = rs.getString("COLOR"); 37 | } 38 | rs.close(); 39 | pstmt.close(); 40 | connection.close(); 41 | } 42 | 43 | public static ArrayList findAll() throws SQLException { 44 | ArrayList all = new ArrayList(); 45 | Ingredient base = new Ingredient(); 46 | base.connect(); 47 | PreparedStatement pstmt = base.connection 48 | .prepareStatement("SELECT * FROM INGREDIENTS"); 49 | ResultSet rs = pstmt.executeQuery(); 50 | while (rs.next()) { 51 | Ingredient p = new Ingredient(); 52 | p.id = rs.getInt("INGREDIENT_ID"); 53 | p.name = rs.getString("INGREDIENT_NAME"); 54 | p.price = rs.getFloat("PRICE"); 55 | p.color = rs.getString("COLOR"); 56 | all.add(p); 57 | } 58 | rs.close(); 59 | pstmt.close(); 60 | base.connection.close(); 61 | return all; 62 | } 63 | 64 | public void setName(String name) { 65 | this.name = name; 66 | } 67 | 68 | public String getName() { 69 | return this.name; 70 | } 71 | 72 | public Integer getId() { 73 | return id; 74 | } 75 | 76 | public void setId(Integer id) { 77 | this.id = id; 78 | } 79 | 80 | public Float getPrice() { 81 | return price; 82 | } 83 | 84 | public String description() { 85 | return getName(); 86 | } 87 | 88 | 89 | } 90 | -------------------------------------------------------------------------------- /2019-aug/1.persistence pattern active record/src/com/alg/order/model/Item.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | public interface Item { 4 | 5 | public Float getPrice(); 6 | 7 | public String description(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /2019-aug/1.persistence pattern active record/src/com/alg/order/model/Order.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | import java.sql.PreparedStatement; 4 | import java.sql.ResultSet; 5 | import java.sql.SQLException; 6 | import java.util.ArrayList; 7 | 8 | import com.alg.order.db.Base; 9 | 10 | public class Order extends Base implements Item { 11 | public Integer id; 12 | public Float price; 13 | public String description; 14 | 15 | public Order() { 16 | price = 0.0f; 17 | description = "Order with "; 18 | } 19 | 20 | public void find(Integer id) throws SQLException { 21 | this.connect(); 22 | PreparedStatement pstmt = connection 23 | .prepareStatement("SELECT * FROM ORDERS WHERE ORDER_ID = ? "); 24 | pstmt.setInt(1, this.id); 25 | ResultSet rs = pstmt.executeQuery(); 26 | while (rs.next()) { 27 | this.price = rs.getFloat("PRICE"); 28 | this.description = rs.getString("DESCRIPTION"); 29 | } 30 | rs.close(); 31 | pstmt.close(); 32 | connection.close(); 33 | } 34 | 35 | public void save() throws SQLException { 36 | this.connect(); 37 | PreparedStatement pstmt = connection 38 | .prepareStatement("insert into ORDERS " 39 | + "(DESCRIPTION, PRICE)" + "values (?, ?)"); 40 | pstmt.setString(1, this.description); 41 | pstmt.setFloat(2, this.price); 42 | pstmt.execute(); 43 | pstmt.close(); 44 | connection.close(); 45 | } 46 | 47 | public static ArrayList findAll() throws SQLException { 48 | ArrayList all = new ArrayList(); 49 | Order base = new Order(); 50 | base.connect(); 51 | PreparedStatement pstmt = base.connection 52 | .prepareStatement("SELECT * FROM ORDERS ORDER BY ORDER_ID DESC"); 53 | ResultSet rs = pstmt.executeQuery(); 54 | while (rs.next()) { 55 | Order p = new Order(); 56 | p.id = rs.getInt("ORDER_ID"); 57 | p.description = rs.getString("DESCRIPTION"); 58 | p.price = rs.getFloat("PRICE"); 59 | all.add(p); 60 | } 61 | rs.close(); 62 | pstmt.close(); 63 | base.connection.close(); 64 | return all; 65 | } 66 | public void decorate(Item item) { 67 | this.price = this.price + item.getPrice(); 68 | this.description = this.description + " " + item.description(); 69 | } 70 | 71 | public String description() { 72 | return description; 73 | } 74 | 75 | public Float getPrice() { 76 | return price; 77 | } 78 | 79 | 80 | } 81 | -------------------------------------------------------------------------------- /2019-aug/1.persistence pattern active record/src/com/alg/order/model/Product.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | import java.sql.PreparedStatement; 4 | import java.sql.ResultSet; 5 | import java.sql.SQLException; 6 | import java.util.ArrayList; 7 | 8 | import com.alg.order.db.Base; 9 | 10 | public class Product extends Base implements Item { 11 | private Integer id; 12 | private String name; 13 | private Float price; 14 | 15 | public Product() { 16 | 17 | } 18 | 19 | public Product(Integer id, String name, Float price) { 20 | super(); 21 | this.id = id; 22 | this.name = name; 23 | this.price = price; 24 | } 25 | 26 | public void find(Integer id) throws SQLException { 27 | this.connect(); 28 | PreparedStatement pstmt = connection 29 | .prepareStatement("SELECT * FROM PRODUCTS WHERE PRODUCT_ID = ? "); 30 | pstmt.setInt(1, this.id); 31 | ResultSet rs = pstmt.executeQuery(); 32 | while (rs.next()) { 33 | this.name = rs.getString("PRODUCT_NAME"); 34 | this.price = rs.getFloat("PRICE"); 35 | } 36 | rs.close(); 37 | pstmt.close(); 38 | connection.close(); 39 | } 40 | 41 | public static ArrayList findAll() throws SQLException { 42 | ArrayList all = new ArrayList(); 43 | Product base = new Product(); 44 | base.connect(); 45 | PreparedStatement pstmt = base.connection 46 | .prepareStatement("SELECT * FROM PRODUCTS"); 47 | ResultSet rs = pstmt.executeQuery(); 48 | while (rs.next()) { 49 | Product p = new Product(); 50 | p.id = rs.getInt("PRODUCT_ID"); 51 | p.name = rs.getString("PRODUCT_NAME"); 52 | p.price = rs.getFloat("PRICE"); 53 | all.add(p); 54 | } 55 | rs.close(); 56 | pstmt.close(); 57 | base.connection.close(); 58 | return all; 59 | } 60 | 61 | public void setName(String name) { 62 | this.name = name; 63 | } 64 | 65 | public String getName() { 66 | return this.name; 67 | } 68 | 69 | public Integer getId() { 70 | return id; 71 | } 72 | 73 | public void setId(Integer id) { 74 | this.id = id; 75 | } 76 | 77 | public Float getPrice() { 78 | return price; 79 | } 80 | 81 | public String description() { 82 | return getName(); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /2019-aug/1.persistence pattern active record/src/com/alg/order/ui/Test.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.ui; 2 | 3 | import java.awt.Dimension; 4 | import java.awt.Toolkit; 5 | 6 | import javax.swing.JFrame; 7 | import javax.swing.WindowConstants; 8 | 9 | public class Test { 10 | 11 | public static void main(String[] args) { 12 | JFrame frame; 13 | frame = new JFrame("Simple Ordering Application"); 14 | frame.setContentPane(new ContentPanel()); 15 | frame.pack(); 16 | Dimension frameDim = new Dimension(400, 400); 17 | Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 18 | frame.setLocation(screenSize.width / 2 - frameDim.width / 2, 19 | screenSize.height / 2 - frameDim.height / 2); 20 | frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 21 | frame.setSize(frameDim); 22 | frame.setVisible(true); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /2019-aug/2.persistence pattern data access object/src/com/alg/order/db/AbstractDao.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.db; 2 | 3 | import java.sql.Connection; 4 | import java.sql.DriverManager; 5 | import java.sql.SQLException; 6 | import java.util.Properties; 7 | 8 | public abstract class AbstractDao implements IDao { 9 | protected Connection connection; 10 | 11 | protected void connect() throws SQLException { 12 | String url = "jdbc:mysql://localhost:3306/test"; 13 | String user = "algo"; 14 | String password = "algo"; 15 | // Load the Oracle JDBC driver 16 | try { 17 | Class.forName("com.mysql.jdbc.Driver"); 18 | } catch (ClassNotFoundException e) { 19 | e.printStackTrace(); 20 | } 21 | 22 | Properties properties = new Properties(); 23 | properties.setProperty("user", user); 24 | properties.setProperty("password", password); 25 | properties.setProperty("useSSL", "false"); 26 | properties.setProperty("autoReconnect", "true"); 27 | 28 | // Connect to the database 29 | connection = DriverManager.getConnection(url, properties); 30 | } 31 | 32 | protected void close() throws SQLException { 33 | connection.close(); 34 | } 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /2019-aug/2.persistence pattern data access object/src/com/alg/order/db/Entity.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.db; 2 | 3 | public interface Entity { 4 | public abstract Integer getId(); 5 | 6 | public abstract void setId(Integer id); 7 | } 8 | -------------------------------------------------------------------------------- /2019-aug/2.persistence pattern data access object/src/com/alg/order/db/IDao.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.db; 2 | 3 | import java.util.List; 4 | 5 | public interface IDao { 6 | 7 | E find(Integer id) throws Exception; 8 | 9 | void save(E entity) throws Exception; 10 | 11 | boolean delete(Integer id) throws Exception; 12 | 13 | boolean update(E entity) throws Exception; 14 | 15 | List findAll() throws Exception; 16 | } 17 | -------------------------------------------------------------------------------- /2019-aug/2.persistence pattern data access object/src/com/alg/order/db/IngredientDao.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.db; 2 | 3 | import java.sql.PreparedStatement; 4 | import java.sql.ResultSet; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import com.alg.order.model.Ingredient; 9 | 10 | public class IngredientDao extends AbstractDao { 11 | 12 | @Override 13 | public Ingredient find(Integer id) throws Exception { 14 | Ingredient ingredient = null; 15 | connect(); 16 | PreparedStatement pstmt = connection 17 | .prepareStatement("SELECT * FROM INGREDIENTS WHERE INGREDIENT_ID = ? "); 18 | pstmt.setInt(1, id); 19 | ResultSet rs = pstmt.executeQuery(); 20 | if (rs.next()) { 21 | new Ingredient(rs.getInt("INGREDIENT_ID"), 22 | rs.getString("INGREDIENT_NAME"), rs.getFloat("PRICE"), 23 | rs.getString("COLOR")); 24 | } 25 | rs.close(); 26 | pstmt.close(); 27 | close(); 28 | return ingredient; 29 | } 30 | 31 | @Override 32 | public void save(Ingredient entity) throws Exception { 33 | connect(); 34 | PreparedStatement pstmt = connection 35 | .prepareStatement("insert into INGREDIENTS " 36 | + "(INGREDIENT_ID, INGREDIENT_NAME, PRICE, COLOR)" 37 | + "values (?, ?, ?, ?)"); 38 | pstmt.setInt(0, entity.getId()); 39 | pstmt.setString(1, entity.getName()); 40 | pstmt.setFloat(2, entity.getPrice()); 41 | pstmt.setString(3, entity.getColor()); 42 | pstmt.execute(); 43 | pstmt.close(); 44 | close(); 45 | } 46 | 47 | @Override 48 | public boolean delete(Integer id) throws Exception { 49 | connect(); 50 | PreparedStatement pstmt = connection 51 | .prepareStatement("DELETE FROM INGREDIENTS WHERE PRODUCT_ID = ?"); 52 | pstmt.setInt(0, id); 53 | boolean res = pstmt.executeUpdate() > 0; 54 | pstmt.close(); 55 | close(); 56 | return res; 57 | } 58 | 59 | @Override 60 | public List findAll() throws Exception { 61 | ArrayList all = new ArrayList(); 62 | connect(); 63 | PreparedStatement pstmt = connection 64 | .prepareStatement("SELECT * FROM INGREDIENTS"); 65 | ResultSet rs = pstmt.executeQuery(); 66 | while (rs.next()) { 67 | Ingredient p = new Ingredient(); 68 | p.setId(rs.getInt("INGREDIENT_ID")); 69 | p.setName(rs.getString("INGREDIENT_NAME")); 70 | p.setPrice(rs.getFloat("PRICE")); 71 | p.setColor(rs.getString("COLOR")); 72 | all.add(p); 73 | } 74 | rs.close(); 75 | pstmt.close(); 76 | close(); 77 | return all; 78 | } 79 | 80 | @Override 81 | public boolean update(Ingredient entity) throws Exception { 82 | connect(); 83 | PreparedStatement pstmt = connection 84 | .prepareStatement("UPDATE INGREDIENTS SET INGREDIENT_ID = ?, INGREDIENT_NAME = ?, PRICE = ?, COLOR=?)"); 85 | pstmt.setInt(0, entity.getId()); 86 | pstmt.setString(1, entity.getName()); 87 | pstmt.setFloat(2, entity.getPrice()); 88 | pstmt.setString(3, entity.getColor()); 89 | boolean res = pstmt.executeUpdate() > 0; 90 | pstmt.close(); 91 | close(); 92 | return res; 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /2019-aug/2.persistence pattern data access object/src/com/alg/order/db/OrderDao.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.db; 2 | 3 | import java.sql.PreparedStatement; 4 | import java.sql.ResultSet; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import com.alg.order.model.Order; 9 | 10 | public class OrderDao extends AbstractDao { 11 | 12 | @Override 13 | public Order find(Integer id) throws Exception { 14 | Order order = null; 15 | connect(); 16 | PreparedStatement pstmt = connection 17 | .prepareStatement("SELECT * FROM ORDERS WHERE ORDER_ID = ? "); 18 | pstmt.setInt(1, id); 19 | ResultSet rs = pstmt.executeQuery(); 20 | if (rs.next()) { 21 | new Order(rs.getInt("ORDER_ID"), rs.getFloat("PRICE"), 22 | rs.getString("DESCRIPTION")); 23 | } 24 | rs.close(); 25 | pstmt.close(); 26 | close(); 27 | return order; 28 | } 29 | 30 | @Override 31 | public void save(Order entity) throws Exception { 32 | connect(); 33 | PreparedStatement pstmt = connection 34 | .prepareStatement("INSERT INTO ORDERS " 35 | + "(DESCRIPTION, PRICE)" + "values (?, ?)"); 36 | pstmt.setString(1, entity.getDescription()); 37 | pstmt.setFloat(2, entity.getPrice()); 38 | pstmt.execute(); 39 | pstmt.close(); 40 | connection.close(); 41 | } 42 | 43 | @Override 44 | public boolean delete(Integer id) throws Exception { 45 | connect(); 46 | PreparedStatement pstmt = connection 47 | .prepareStatement("DELETE FROM ORDERS WHERE ORDER_ID = ?"); 48 | pstmt.setInt(0, id); 49 | boolean res = pstmt.executeUpdate() > 0; 50 | pstmt.close(); 51 | close(); 52 | return res; 53 | } 54 | 55 | @Override 56 | public List findAll() throws Exception { 57 | ArrayList all = new ArrayList(); 58 | connect(); 59 | PreparedStatement pstmt = connection 60 | .prepareStatement("SELECT * FROM ORDERS ORDER BY ORDER_ID DESC"); 61 | ResultSet rs = pstmt.executeQuery(); 62 | while (rs.next()) { 63 | Order p = new Order(); 64 | p.setId(rs.getInt("ORDER_ID")); 65 | p.setDescription(rs.getString("DESCRIPTION")); 66 | p.setPrice(rs.getFloat("PRICE")); 67 | all.add(p); 68 | } 69 | rs.close(); 70 | pstmt.close(); 71 | close(); 72 | return all; 73 | } 74 | 75 | @Override 76 | public boolean update(Order entity) throws Exception { 77 | connect(); 78 | PreparedStatement pstmt = connection 79 | .prepareStatement("UPDATE ORDERS SET ORDER_ID = ?, ORDEER_DESCRIPTION = ?, PRICE = ?)"); 80 | pstmt.setInt(0, entity.getId()); 81 | pstmt.setString(1, entity.getDescription()); 82 | pstmt.setFloat(2, entity.getPrice()); 83 | boolean res = pstmt.executeUpdate() > 0; 84 | pstmt.close(); 85 | close(); 86 | return res; 87 | 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /2019-aug/2.persistence pattern data access object/src/com/alg/order/db/ProductDao.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.db; 2 | 3 | import java.sql.PreparedStatement; 4 | import java.sql.ResultSet; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import com.alg.order.model.Product; 9 | 10 | public class ProductDao extends AbstractDao { 11 | 12 | @Override 13 | public Product find(Integer id) throws Exception { 14 | Product p = null; 15 | connect(); 16 | PreparedStatement pstmt = connection 17 | .prepareStatement("SELECT * FROM PRODUCTS WHERE PRODUCT_ID = ? "); 18 | pstmt.setInt(1, id); 19 | ResultSet rs = pstmt.executeQuery(); 20 | if (rs.next()) { 21 | p = new Product(rs.getInt("PRODUCT_ID"), 22 | rs.getString("PRODUCT_NAME"), rs.getFloat("PRICE")); 23 | } 24 | rs.close(); 25 | pstmt.close(); 26 | connection.close(); 27 | return p; 28 | } 29 | 30 | @Override 31 | public void save(Product entity) throws Exception { 32 | connect(); 33 | PreparedStatement pstmt = connection 34 | .prepareStatement("INSERT INTO PRODUCTS " 35 | + "(PRODUCT_ID, PRODUCT_NAME, PRICE)" 36 | + "values (?, ?, ?)"); 37 | pstmt.setInt(0, entity.getId()); 38 | pstmt.setString(1, entity.getName()); 39 | pstmt.setFloat(2, entity.getPrice()); 40 | pstmt.execute(); 41 | pstmt.close(); 42 | close(); 43 | } 44 | 45 | @Override 46 | public boolean delete(Integer id) throws Exception { 47 | connect(); 48 | PreparedStatement pstmt = connection 49 | .prepareStatement("DELETE FROM PRODUCTS WHERE PRODUCT_ID = ?"); 50 | pstmt.setInt(0, id); 51 | boolean res = pstmt.executeUpdate() > 0; 52 | pstmt.close(); 53 | close(); 54 | return res; 55 | 56 | } 57 | 58 | @Override 59 | public List findAll() throws Exception { 60 | ArrayList all = new ArrayList(); 61 | connect(); 62 | PreparedStatement pstmt = connection 63 | .prepareStatement("SELECT * FROM PRODUCTS"); 64 | ResultSet rs = pstmt.executeQuery(); 65 | while (rs.next()) { 66 | Product p = new Product(); 67 | p.setId(rs.getInt("PRODUCT_ID")); 68 | p.setName(rs.getString("PRODUCT_NAME")); 69 | p.setPrice(rs.getFloat("PRICE")); 70 | all.add(p); 71 | } 72 | rs.close(); 73 | pstmt.close(); 74 | close(); 75 | return all; 76 | } 77 | 78 | @Override 79 | public boolean update(Product entity) throws Exception { 80 | connect(); 81 | PreparedStatement pstmt = connection 82 | .prepareStatement("UPDATE PRODUCTS SET PRODUCT_ID = ?, PRODUCT_NAME = ?, PRICE = ?)"); 83 | pstmt.setInt(0, entity.getId()); 84 | pstmt.setString(1, entity.getName()); 85 | pstmt.setFloat(2, entity.getPrice()); 86 | boolean res = pstmt.executeUpdate() > 0; 87 | pstmt.close(); 88 | close(); 89 | return res; 90 | 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /2019-aug/2.persistence pattern data access object/src/com/alg/order/model/Ingredient.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | import com.alg.order.db.Entity; 4 | 5 | public class Ingredient implements Item, Entity { 6 | private Integer id; 7 | private String name; 8 | private Float price; 9 | private String color; 10 | 11 | public Ingredient() { 12 | 13 | } 14 | 15 | public Ingredient(Integer id, String name, Float price, String color) { 16 | super(); 17 | this.id = id; 18 | this.name = name; 19 | this.price = price; 20 | this.color = color; 21 | } 22 | 23 | public void setName(String name) { 24 | this.name = name; 25 | } 26 | 27 | public String getName() { 28 | return this.name; 29 | } 30 | 31 | public Integer getId() { 32 | return id; 33 | } 34 | 35 | public void setId(Integer id) { 36 | this.id = id; 37 | } 38 | 39 | public Float getPrice() { 40 | return price; 41 | } 42 | 43 | public String description() { 44 | return getName(); 45 | } 46 | 47 | public String getColor() { 48 | return color; 49 | } 50 | 51 | public void setColor(String color) { 52 | this.color = color; 53 | } 54 | 55 | public void setPrice(Float price) { 56 | this.price = price; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /2019-aug/2.persistence pattern data access object/src/com/alg/order/model/Item.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | public interface Item { 4 | 5 | public Float getPrice(); 6 | 7 | public String description(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /2019-aug/2.persistence pattern data access object/src/com/alg/order/model/Order.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | import com.alg.order.db.Entity; 4 | 5 | public class Order implements Entity { 6 | private Integer id; 7 | private Float price; 8 | private String description; 9 | 10 | public Order() { 11 | price = 0.0f; 12 | description = "Order with "; 13 | } 14 | 15 | public Order(Integer id, Float price, String description) { 16 | super(); 17 | this.id = id; 18 | this.price = price; 19 | this.description = description; 20 | } 21 | 22 | public void decorate(Item item) { 23 | this.price = this.price + item.getPrice(); 24 | this.description = this.description + " " + item.description(); 25 | } 26 | 27 | public String description() { 28 | return description; 29 | } 30 | 31 | public Float getPrice() { 32 | return price; 33 | } 34 | 35 | public Integer getId() { 36 | return id; 37 | } 38 | 39 | public void setId(Integer id) { 40 | this.id = id; 41 | } 42 | 43 | public String getDescription() { 44 | return description; 45 | } 46 | 47 | public void setDescription(String description) { 48 | this.description = description; 49 | } 50 | 51 | public void setPrice(Float price) { 52 | this.price = price; 53 | } 54 | 55 | 56 | } 57 | -------------------------------------------------------------------------------- /2019-aug/2.persistence pattern data access object/src/com/alg/order/model/Product.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | import com.alg.order.db.Entity; 4 | 5 | public class Product implements Item, Entity { 6 | private Integer id; 7 | private String name; 8 | private Float price; 9 | 10 | public Product() { 11 | 12 | } 13 | 14 | public Product(Integer id, String name, Float price) { 15 | super(); 16 | this.id = id; 17 | this.name = name; 18 | this.price = price; 19 | } 20 | 21 | public void setName(String name) { 22 | this.name = name; 23 | } 24 | 25 | public String getName() { 26 | return this.name; 27 | } 28 | 29 | public Integer getId() { 30 | return id; 31 | } 32 | 33 | public void setId(Integer id) { 34 | this.id = id; 35 | } 36 | 37 | public Float getPrice() { 38 | return price; 39 | } 40 | 41 | public void setPrice(Float price) { 42 | this.price = price; 43 | } 44 | 45 | public String description() { 46 | return getName(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /2019-aug/2.persistence pattern data access object/src/com/alg/order/ui/Test.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.ui; 2 | 3 | import java.awt.Dimension; 4 | import java.awt.Toolkit; 5 | 6 | import javax.swing.JFrame; 7 | import javax.swing.WindowConstants; 8 | 9 | import com.alg.order.db.IngredientDao; 10 | import com.alg.order.db.OrderDao; 11 | import com.alg.order.db.ProductDao; 12 | 13 | public class Test { 14 | 15 | public static void main(String[] args) { 16 | JFrame frame; 17 | frame = new JFrame("Simple Ordering Application"); 18 | frame.setContentPane(new ContentPanel(new ProductDao(), new IngredientDao(), new OrderDao())); 19 | frame.pack(); 20 | Dimension frameDim = new Dimension(400, 400); 21 | Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 22 | frame.setLocation(screenSize.width / 2 - frameDim.width / 2, 23 | screenSize.height / 2 - frameDim.height / 2); 24 | frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 25 | frame.setSize(frameDim); 26 | frame.setVisible(true); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /2019-aug/3.persistence pattern repository/src/com/alg/order/db/AbstractRepository.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.db; 2 | 3 | import java.sql.Connection; 4 | import java.sql.DriverManager; 5 | import java.sql.SQLException; 6 | import java.util.Properties; 7 | 8 | public abstract class AbstractRepository implements IRepository { 9 | protected Connection connection; 10 | 11 | protected void connect() throws SQLException { 12 | String url = "jdbc:mysql://localhost:3306/test"; 13 | String user = "algo"; 14 | String password = "algo"; 15 | // Load the Oracle JDBC driver 16 | try { 17 | Class.forName("com.mysql.jdbc.Driver"); 18 | } catch (ClassNotFoundException e) { 19 | e.printStackTrace(); 20 | } 21 | 22 | Properties properties = new Properties(); 23 | properties.setProperty("user", user); 24 | properties.setProperty("password", password); 25 | properties.setProperty("useSSL", "false"); 26 | properties.setProperty("autoReconnect", "true"); 27 | 28 | // Connect to the database 29 | connection = DriverManager.getConnection(url, properties); 30 | } 31 | 32 | protected void close() throws SQLException { 33 | connection.close(); 34 | } 35 | 36 | 37 | } 38 | -------------------------------------------------------------------------------- /2019-aug/3.persistence pattern repository/src/com/alg/order/db/Entity.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.db; 2 | 3 | public interface Entity { 4 | public abstract Integer getId(); 5 | 6 | public abstract void setId(Integer id); 7 | } 8 | -------------------------------------------------------------------------------- /2019-aug/3.persistence pattern repository/src/com/alg/order/db/IRepository.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.db; 2 | 3 | import java.util.List; 4 | 5 | import com.alg.order.db.specifications.ISqlSpecification; 6 | 7 | public interface IRepository { 8 | 9 | List query(ISqlSpecification specification) throws Exception; 10 | 11 | void save(E entity) throws Exception; 12 | 13 | boolean delete(E entity) throws Exception; 14 | 15 | boolean update(E entity) throws Exception; 16 | 17 | List findAll() throws Exception; 18 | } 19 | -------------------------------------------------------------------------------- /2019-aug/3.persistence pattern repository/src/com/alg/order/db/IngredientRepository.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.db; 2 | 3 | import java.sql.PreparedStatement; 4 | import java.sql.ResultSet; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import com.alg.order.db.specifications.ISqlSpecification; 9 | import com.alg.order.model.Ingredient; 10 | 11 | public class IngredientRepository extends AbstractRepository { 12 | 13 | @Override 14 | public void save(Ingredient entity) throws Exception { 15 | connect(); 16 | PreparedStatement pstmt = connection 17 | .prepareStatement("insert into INGREDIENTS " 18 | + "(INGREDIENT_ID, INGREDIENT_NAME, PRICE, COLOR)" 19 | + "values (?, ?, ?, ?)"); 20 | pstmt.setInt(0, entity.getId()); 21 | pstmt.setString(1, entity.getName()); 22 | pstmt.setFloat(2, entity.getPrice()); 23 | pstmt.setString(3, entity.getColor()); 24 | pstmt.execute(); 25 | pstmt.close(); 26 | close(); 27 | } 28 | 29 | @Override 30 | public boolean delete(Ingredient entity) throws Exception { 31 | connect(); 32 | PreparedStatement pstmt = connection 33 | .prepareStatement("DELETE FROM INGREDIENTS WHERE PRODUCT_ID = ?"); 34 | pstmt.setInt(0, entity.getId()); 35 | boolean res = pstmt.executeUpdate() > 0; 36 | pstmt.close(); 37 | close(); 38 | return res; 39 | } 40 | 41 | @Override 42 | public List findAll() throws Exception { 43 | ArrayList all = new ArrayList(); 44 | connect(); 45 | PreparedStatement pstmt = connection 46 | .prepareStatement("SELECT * FROM INGREDIENTS"); 47 | ResultSet rs = pstmt.executeQuery(); 48 | while (rs.next()) { 49 | Ingredient p = new Ingredient(); 50 | p.setId(rs.getInt("INGREDIENT_ID")); 51 | p.setName(rs.getString("INGREDIENT_NAME")); 52 | p.setPrice(rs.getFloat("PRICE")); 53 | p.setColor(rs.getString("COLOR")); 54 | all.add(p); 55 | } 56 | rs.close(); 57 | pstmt.close(); 58 | close(); 59 | return all; 60 | } 61 | 62 | @Override 63 | public boolean update(Ingredient entity) throws Exception { 64 | connect(); 65 | PreparedStatement pstmt = connection 66 | .prepareStatement("UPDATE INGREDIENTS SET INGREDIENT_ID = ?, INGREDIENT_NAME = ?, PRICE = ?, COLOR=?)"); 67 | pstmt.setInt(0, entity.getId()); 68 | pstmt.setString(1, entity.getName()); 69 | pstmt.setFloat(2, entity.getPrice()); 70 | pstmt.setString(3, entity.getColor()); 71 | boolean res = pstmt.executeUpdate() > 0; 72 | pstmt.close(); 73 | close(); 74 | return res; 75 | } 76 | 77 | @Override 78 | public List query(ISqlSpecification specification) 79 | throws Exception { 80 | ArrayList all = new ArrayList(); 81 | connect(); 82 | PreparedStatement pstmt = connection 83 | .prepareStatement("SELECT * FROM INGREDIENTS " + specification.toSqlClauses()); 84 | ResultSet rs = pstmt.executeQuery(); 85 | while (rs.next()) { 86 | Ingredient p = new Ingredient(); 87 | p.setId(rs.getInt("INGREDIENT_ID")); 88 | p.setName(rs.getString("INGREDIENT_NAME")); 89 | p.setPrice(rs.getFloat("PRICE")); 90 | p.setColor(rs.getString("COLOR")); 91 | all.add(p); 92 | } 93 | rs.close(); 94 | pstmt.close(); 95 | close(); 96 | return all; 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /2019-aug/3.persistence pattern repository/src/com/alg/order/db/OrderRepository.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.db; 2 | 3 | import java.sql.PreparedStatement; 4 | import java.sql.ResultSet; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import com.alg.order.db.specifications.ISqlSpecification; 9 | import com.alg.order.model.Order; 10 | 11 | public class OrderRepository extends AbstractRepository { 12 | 13 | @Override 14 | public void save(Order entity) throws Exception { 15 | connect(); 16 | PreparedStatement pstmt = connection 17 | .prepareStatement("INSERT INTO ORDERS " 18 | + "(DESCRIPTION, PRICE)" + "values (?, ?)"); 19 | pstmt.setString(1, entity.getDescription()); 20 | pstmt.setFloat(2, entity.getPrice()); 21 | pstmt.execute(); 22 | pstmt.close(); 23 | connection.close(); 24 | } 25 | 26 | @Override 27 | public boolean delete(Order entity) throws Exception { 28 | connect(); 29 | PreparedStatement pstmt = connection 30 | .prepareStatement("DELETE FROM ORDERS WHERE ORDER_ID = ?"); 31 | pstmt.setInt(0, entity.getId()); 32 | boolean res = pstmt.executeUpdate() > 0; 33 | pstmt.close(); 34 | close(); 35 | return res; 36 | } 37 | 38 | @Override 39 | public List findAll() throws Exception { 40 | ArrayList all = new ArrayList(); 41 | connect(); 42 | PreparedStatement pstmt = connection 43 | .prepareStatement("SELECT * FROM ORDERS ORDER BY ORDER_ID DESC"); 44 | ResultSet rs = pstmt.executeQuery(); 45 | while (rs.next()) { 46 | Order p = new Order(); 47 | p.setId(rs.getInt("ORDER_ID")); 48 | p.setDescription(rs.getString("DESCRIPTION")); 49 | p.setPrice(rs.getFloat("PRICE")); 50 | all.add(p); 51 | } 52 | rs.close(); 53 | pstmt.close(); 54 | close(); 55 | return all; 56 | } 57 | 58 | @Override 59 | public boolean update(Order entity) throws Exception { 60 | connect(); 61 | PreparedStatement pstmt = connection 62 | .prepareStatement("UPDATE ORDERS SET ORDER_ID = ?, ORDEER_DESCRIPTION = ?, PRICE = ?)"); 63 | pstmt.setInt(0, entity.getId()); 64 | pstmt.setString(1, entity.getDescription()); 65 | pstmt.setFloat(2, entity.getPrice()); 66 | boolean res = pstmt.executeUpdate() > 0; 67 | pstmt.close(); 68 | close(); 69 | return res; 70 | 71 | } 72 | 73 | @Override 74 | public List query(ISqlSpecification specification) throws Exception { 75 | ArrayList all = new ArrayList(); 76 | connect(); 77 | PreparedStatement pstmt = connection 78 | .prepareStatement("SELECT * FROM ORDERS ORDER BY ORDER_ID DESC " + specification.toSqlClauses()); 79 | ResultSet rs = pstmt.executeQuery(); 80 | while (rs.next()) { 81 | Order p = new Order(); 82 | p.setId(rs.getInt("ORDER_ID")); 83 | p.setDescription(rs.getString("DESCRIPTION")); 84 | p.setPrice(rs.getFloat("PRICE")); 85 | all.add(p); 86 | } 87 | rs.close(); 88 | pstmt.close(); 89 | close(); 90 | return all; 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /2019-aug/3.persistence pattern repository/src/com/alg/order/db/ProductRepository.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.db; 2 | 3 | import java.sql.PreparedStatement; 4 | import java.sql.ResultSet; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import com.alg.order.db.specifications.ISqlSpecification; 9 | import com.alg.order.model.Product; 10 | 11 | public class ProductRepository extends AbstractRepository { 12 | 13 | @Override 14 | public void save(Product entity) throws Exception { 15 | connect(); 16 | PreparedStatement pstmt = connection 17 | .prepareStatement("INSERT INTO PRODUCTS " 18 | + "(PRODUCT_ID, PRODUCT_NAME, PRICE)" 19 | + "values (?, ?, ?)"); 20 | pstmt.setInt(0, entity.getId()); 21 | pstmt.setString(1, entity.getName()); 22 | pstmt.setFloat(2, entity.getPrice()); 23 | pstmt.execute(); 24 | pstmt.close(); 25 | close(); 26 | } 27 | 28 | @Override 29 | public boolean delete(Product entity) throws Exception { 30 | connect(); 31 | PreparedStatement pstmt = connection 32 | .prepareStatement("DELETE FROM PRODUCTS WHERE PRODUCT_ID = ?"); 33 | pstmt.setInt(0, entity.getId()); 34 | boolean res = pstmt.executeUpdate() > 0; 35 | pstmt.close(); 36 | close(); 37 | return res; 38 | 39 | } 40 | 41 | @Override 42 | public List findAll() throws Exception { 43 | ArrayList all = new ArrayList(); 44 | connect(); 45 | PreparedStatement pstmt = connection 46 | .prepareStatement("SELECT * FROM PRODUCTS"); 47 | ResultSet rs = pstmt.executeQuery(); 48 | while (rs.next()) { 49 | Product p = new Product(); 50 | p.setId(rs.getInt("PRODUCT_ID")); 51 | p.setName(rs.getString("PRODUCT_NAME")); 52 | p.setPrice(rs.getFloat("PRICE")); 53 | all.add(p); 54 | } 55 | rs.close(); 56 | pstmt.close(); 57 | close(); 58 | return all; 59 | } 60 | 61 | @Override 62 | public boolean update(Product entity) throws Exception { 63 | connect(); 64 | PreparedStatement pstmt = connection 65 | .prepareStatement("UPDATE PRODUCTS SET PRODUCT_ID = ?, PRODUCT_NAME = ?, PRICE = ?)"); 66 | pstmt.setInt(0, entity.getId()); 67 | pstmt.setString(1, entity.getName()); 68 | pstmt.setFloat(2, entity.getPrice()); 69 | boolean res = pstmt.executeUpdate() > 0; 70 | pstmt.close(); 71 | close(); 72 | return res; 73 | 74 | } 75 | 76 | @Override 77 | public List query(ISqlSpecification specification) 78 | throws Exception { 79 | ArrayList all = new ArrayList(); 80 | connect(); 81 | PreparedStatement pstmt = connection 82 | .prepareStatement(specification.toSqlClauses()); 83 | ResultSet rs = pstmt.executeQuery(); 84 | while (rs.next()) { 85 | Product p = new Product(); 86 | p.setId(rs.getInt("PRODUCT_ID")); 87 | p.setName(rs.getString("PRODUCT_NAME")); 88 | p.setPrice(rs.getFloat("PRICE")); 89 | all.add(p); 90 | } 91 | rs.close(); 92 | pstmt.close(); 93 | close(); 94 | return all; 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /2019-aug/3.persistence pattern repository/src/com/alg/order/db/specifications/ISqlSpecification.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.db.specifications; 2 | 3 | public interface ISqlSpecification { 4 | String toSqlClauses(); 5 | } 6 | -------------------------------------------------------------------------------- /2019-aug/3.persistence pattern repository/src/com/alg/order/db/specifications/ProductSpecificationByName.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.db.specifications; 2 | 3 | public class ProductSpecificationByName implements ISqlSpecification { 4 | private String name; 5 | 6 | public ProductSpecificationByName(String name) { 7 | super(); 8 | this.name = name; 9 | } 10 | 11 | @Override 12 | public String toSqlClauses() { 13 | return String.format("SELECT * FROM PRODUCTS WHERE PRODUCT_NAME = %s", name); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /2019-aug/3.persistence pattern repository/src/com/alg/order/db/specifications/ProductSpecificationByPriceRange.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.db.specifications; 2 | 3 | public class ProductSpecificationByPriceRange implements ISqlSpecification { 4 | private float min_price; 5 | private float max_price; 6 | 7 | public ProductSpecificationByPriceRange(float min_price, float max_price) { 8 | super(); 9 | this.min_price = min_price; 10 | this.max_price = max_price; 11 | } 12 | 13 | @Override 14 | public String toSqlClauses() { 15 | return String.format("SELECT * FROM PRODUCTS WHERE PRICE BETWEEN %s AND %s", min_price, max_price); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /2019-aug/3.persistence pattern repository/src/com/alg/order/model/Ingredient.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | import com.alg.order.db.Entity; 4 | 5 | public class Ingredient implements Item, Entity { 6 | private Integer id; 7 | private String name; 8 | private Float price; 9 | private String color; 10 | 11 | public Ingredient() { 12 | 13 | } 14 | 15 | public Ingredient(Integer id, String name, Float price, String color) { 16 | super(); 17 | this.id = id; 18 | this.name = name; 19 | this.price = price; 20 | this.color = color; 21 | } 22 | 23 | public void setName(String name) { 24 | this.name = name; 25 | } 26 | 27 | public String getName() { 28 | return this.name; 29 | } 30 | 31 | public Integer getId() { 32 | return id; 33 | } 34 | 35 | public void setId(Integer id) { 36 | this.id = id; 37 | } 38 | 39 | public Float getPrice() { 40 | return price; 41 | } 42 | 43 | public String description() { 44 | return getName(); 45 | } 46 | 47 | public String getColor() { 48 | return color; 49 | } 50 | 51 | public void setColor(String color) { 52 | this.color = color; 53 | } 54 | 55 | public void setPrice(Float price) { 56 | this.price = price; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /2019-aug/3.persistence pattern repository/src/com/alg/order/model/Item.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | public interface Item { 4 | 5 | public Float getPrice(); 6 | 7 | public String description(); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /2019-aug/3.persistence pattern repository/src/com/alg/order/model/Order.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | import com.alg.order.db.Entity; 4 | 5 | public class Order implements Entity { 6 | private Integer id; 7 | private Float price; 8 | private String description; 9 | 10 | public Order() { 11 | price = 0.0f; 12 | description = "Order with "; 13 | } 14 | 15 | public Order(Integer id, Float price, String description) { 16 | super(); 17 | this.id = id; 18 | this.price = price; 19 | this.description = description; 20 | } 21 | 22 | public void decorate(Item item) { 23 | this.price = this.price + item.getPrice(); 24 | this.description = this.description + " " + item.description(); 25 | } 26 | 27 | public String description() { 28 | return description; 29 | } 30 | 31 | public Float getPrice() { 32 | return price; 33 | } 34 | 35 | public Integer getId() { 36 | return id; 37 | } 38 | 39 | public void setId(Integer id) { 40 | this.id = id; 41 | } 42 | 43 | public String getDescription() { 44 | return description; 45 | } 46 | 47 | public void setDescription(String description) { 48 | this.description = description; 49 | } 50 | 51 | public void setPrice(Float price) { 52 | this.price = price; 53 | } 54 | 55 | 56 | } 57 | -------------------------------------------------------------------------------- /2019-aug/3.persistence pattern repository/src/com/alg/order/model/Product.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | import com.alg.order.db.Entity; 4 | 5 | public class Product implements Item, Entity { 6 | private Integer id; 7 | private String name; 8 | private Float price; 9 | 10 | public Product() { 11 | 12 | } 13 | 14 | public Product(Integer id, String name, Float price) { 15 | super(); 16 | this.id = id; 17 | this.name = name; 18 | this.price = price; 19 | } 20 | 21 | public void setName(String name) { 22 | this.name = name; 23 | } 24 | 25 | public String getName() { 26 | return this.name; 27 | } 28 | 29 | public Integer getId() { 30 | return id; 31 | } 32 | 33 | public void setId(Integer id) { 34 | this.id = id; 35 | } 36 | 37 | public Float getPrice() { 38 | return price; 39 | } 40 | 41 | public void setPrice(Float price) { 42 | this.price = price; 43 | } 44 | 45 | public String description() { 46 | return getName(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /2019-aug/3.persistence pattern repository/src/com/alg/order/ui/Test.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.ui; 2 | 3 | import java.awt.Dimension; 4 | import java.awt.Toolkit; 5 | 6 | import javax.swing.JFrame; 7 | import javax.swing.WindowConstants; 8 | 9 | import com.alg.order.db.IngredientRepository; 10 | import com.alg.order.db.OrderRepository; 11 | import com.alg.order.db.ProductRepository; 12 | 13 | public class Test { 14 | 15 | public static void main(String[] args) { 16 | JFrame frame; 17 | frame = new JFrame("Simple Ordering Application"); 18 | frame.setContentPane(new ContentPanel(new ProductRepository(), 19 | new IngredientRepository(), new OrderRepository())); 20 | frame.pack(); 21 | Dimension frameDim = new Dimension(400, 400); 22 | Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 23 | frame.setLocation(screenSize.width / 2 - frameDim.width / 2, 24 | screenSize.height / 2 - frameDim.height / 2); 25 | frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 26 | frame.setSize(frameDim); 27 | frame.setVisible(true); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/common/AbstractId.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.common; 2 | 3 | public abstract class AbstractId extends AssertionConcern implements Entity { 4 | private String id; 5 | 6 | protected AbstractId(String anId) { 7 | this(); 8 | this.setId(anId); 9 | } 10 | 11 | protected AbstractId() { 12 | super(); 13 | } 14 | 15 | private void setId(String anId) { 16 | this.assertArgumentNotEmpty(anId, "The basic identity is required."); 17 | this.assertArgumentLength(anId, 36, 18 | "The basic identity must be 36 characters."); 19 | this.id = anId; 20 | } 21 | 22 | public String id() { 23 | return this.id; 24 | } 25 | 26 | @Override 27 | public boolean equals(Object anObject) { 28 | boolean equalObjects = false; 29 | 30 | if (anObject != null && this.getClass() == anObject.getClass()) { 31 | AbstractId typedObject = (AbstractId) anObject; 32 | equalObjects = this.id().equals(typedObject.id()); 33 | } 34 | 35 | return equalObjects; 36 | } 37 | 38 | @Override 39 | public int hashCode() { 40 | return this.id().hashCode(); 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return this.getClass().getSimpleName() + " [id=" + id + "]"; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/common/AssertionConcern.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.common; 2 | 3 | public class AssertionConcern { 4 | 5 | protected AssertionConcern() { 6 | super(); 7 | } 8 | 9 | protected void assertArgumentEquals(Object anObject1, Object anObject2, 10 | String aMessage) { 11 | if (!anObject1.equals(anObject2)) { 12 | throw new IllegalArgumentException(aMessage); 13 | } 14 | } 15 | 16 | protected void assertArgumentFalse(boolean aBoolean, String aMessage) { 17 | if (aBoolean) { 18 | throw new IllegalArgumentException(aMessage); 19 | } 20 | } 21 | 22 | protected void assertArgumentLength(String aString, int aMaximum, 23 | String aMessage) { 24 | int length = aString.trim().length(); 25 | if (length > aMaximum) { 26 | throw new IllegalArgumentException(aMessage); 27 | } 28 | } 29 | 30 | protected void assertArgumentLength(String aString, int aMinimum, 31 | int aMaximum, String aMessage) { 32 | int length = aString.trim().length(); 33 | if (length < aMinimum || length > aMaximum) { 34 | throw new IllegalArgumentException(aMessage); 35 | } 36 | } 37 | 38 | protected void assertArgumentNotEmpty(String aString, String aMessage) { 39 | if (aString == null || aString.trim().isEmpty()) { 40 | throw new IllegalArgumentException(aMessage); 41 | } 42 | } 43 | 44 | protected void assertArgumentNotEquals(Object anObject1, Object anObject2, 45 | String aMessage) { 46 | if (anObject1.equals(anObject2)) { 47 | throw new IllegalArgumentException(aMessage); 48 | } 49 | } 50 | 51 | protected void assertArgumentNotNull(Object anObject, String aMessage) { 52 | if (anObject == null) { 53 | throw new IllegalArgumentException(aMessage); 54 | } 55 | } 56 | 57 | protected void assertArgumentRange(double aValue, double aMinimum, 58 | double aMaximum, String aMessage) { 59 | if (aValue < aMinimum || aValue > aMaximum) { 60 | throw new IllegalArgumentException(aMessage); 61 | } 62 | } 63 | 64 | protected void assertArgumentRange(float aValue, float aMinimum, 65 | float aMaximum, String aMessage) { 66 | if (aValue < aMinimum || aValue > aMaximum) { 67 | throw new IllegalArgumentException(aMessage); 68 | } 69 | } 70 | 71 | protected void assertArgumentRange(int aValue, int aMinimum, int aMaximum, 72 | String aMessage) { 73 | if (aValue < aMinimum || aValue > aMaximum) { 74 | throw new IllegalArgumentException(aMessage); 75 | } 76 | } 77 | 78 | protected void assertArgumentRange(long aValue, long aMinimum, 79 | long aMaximum, String aMessage) { 80 | if (aValue < aMinimum || aValue > aMaximum) { 81 | throw new IllegalArgumentException(aMessage); 82 | } 83 | } 84 | 85 | protected void assertArgumentTrue(boolean aBoolean, String aMessage) { 86 | if (!aBoolean) { 87 | throw new IllegalArgumentException(aMessage); 88 | } 89 | } 90 | 91 | protected void assertStateFalse(boolean aBoolean, String aMessage) { 92 | if (aBoolean) { 93 | throw new IllegalStateException(aMessage); 94 | } 95 | } 96 | 97 | protected void assertStateTrue(boolean aBoolean, String aMessage) { 98 | if (!aBoolean) { 99 | throw new IllegalStateException(aMessage); 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/common/Entity.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.common; 2 | 3 | public interface Entity { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/common/ValueObject.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.common; 2 | 3 | public interface ValueObject { 4 | 5 | } 6 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/model/EmailAddress.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | import java.util.regex.Pattern; 4 | 5 | import com.alg.order.common.AssertionConcern; 6 | import com.alg.order.common.ValueObject; 7 | 8 | public final class EmailAddress extends AssertionConcern implements ValueObject { 9 | private String address; 10 | 11 | public EmailAddress() { 12 | super(); 13 | } 14 | 15 | public EmailAddress(String anAddress) { 16 | super(); 17 | this.setAddress(anAddress); 18 | } 19 | 20 | public String address() { 21 | return this.address; 22 | } 23 | 24 | @Override 25 | public boolean equals(Object anObject) { 26 | boolean equalObjects = false; 27 | 28 | if (anObject != null && this.getClass() == anObject.getClass()) { 29 | EmailAddress typedObject = (EmailAddress) anObject; 30 | equalObjects = this.address().equals(typedObject.address()); 31 | } 32 | 33 | return equalObjects; 34 | } 35 | 36 | @Override 37 | public int hashCode() { 38 | return this.address().hashCode(); 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | return "EmailAddress [address=" + address + "]"; 44 | } 45 | 46 | private void setAddress(String anAddress) { 47 | this.assertArgumentNotEmpty(anAddress, "The email address is required."); 48 | this.assertArgumentLength(anAddress, 1, 100, 49 | "Email address must be 100 characters or less."); 50 | this.assertArgumentTrue(Pattern.matches( 51 | "\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*", 52 | anAddress), "Email address format is invalid."); 53 | 54 | this.address = anAddress; 55 | } 56 | } -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/model/Ingredient.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | import com.alg.order.common.Entity; 4 | 5 | public class Ingredient implements Entity { 6 | private IngredientId id; 7 | private String name; 8 | private IngredientPrice price; 9 | private IngredientColor color; 10 | 11 | public Ingredient() { 12 | 13 | } 14 | 15 | public Ingredient(IngredientId id, String name, IngredientPrice price, 16 | IngredientColor color) { 17 | super(); 18 | this.id = id; 19 | this.setName(name); 20 | this.price = price; 21 | this.color = color; 22 | } 23 | 24 | private void setName(String name) { 25 | this.name = name; 26 | } 27 | 28 | public String getName() { 29 | return this.name; 30 | } 31 | 32 | public IngredientId getId() { 33 | return id; 34 | } 35 | 36 | public void setId(IngredientId id) { 37 | this.id = id; 38 | } 39 | 40 | public IngredientPrice getPrice() { 41 | return price; 42 | } 43 | 44 | public IngredientColor getColor() { 45 | return color; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/model/IngredientColor.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | import com.alg.order.common.AssertionConcern; 4 | import com.alg.order.common.ValueObject; 5 | 6 | public class IngredientColor extends AssertionConcern implements ValueObject { 7 | private String color; 8 | 9 | public IngredientColor(String color) { 10 | super(); 11 | 12 | this.setColor(color); 13 | } 14 | 15 | private void setColor(String aColor) { 16 | this.assertArgumentNotEmpty(aColor, "The color is required."); 17 | 18 | this.color = aColor; 19 | } 20 | 21 | public String color() { 22 | return color; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/model/IngredientId.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | import com.alg.order.common.AbstractId; 4 | import com.alg.order.common.ValueObject; 5 | 6 | public class IngredientId extends AbstractId implements ValueObject { 7 | 8 | public IngredientId() { 9 | super(); 10 | // TODO Auto-generated constructor stub 11 | } 12 | 13 | public IngredientId(String anId) { 14 | super(anId); 15 | // TODO Auto-generated constructor stub 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/model/IngredientPrice.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | import com.alg.order.common.AssertionConcern; 4 | import com.alg.order.common.ValueObject; 5 | 6 | public class IngredientPrice extends AssertionConcern implements ValueObject { 7 | private Float price; 8 | 9 | public IngredientPrice(Float price) { 10 | super(); 11 | 12 | this.setPrice(price); 13 | } 14 | 15 | private void setPrice(Float aPrice) { 16 | this.assertArgumentNotNull(aPrice, "Product price is required."); 17 | 18 | this.price = aPrice; 19 | } 20 | 21 | public Float price() { 22 | return price; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/model/Order.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | import com.alg.order.common.Entity; 4 | 5 | public class Order implements Entity { 6 | private OrderId id; 7 | private Float price; 8 | private ProductId product_id; 9 | private IngredientId ingredient_id; 10 | private EmailAddress email_address; 11 | private PostalAddress postal_address; 12 | private Telephone telephone; 13 | 14 | public Order(OrderId id, Float price, ProductId product_id, 15 | IngredientId ingredient_id, EmailAddress email_address, 16 | Telephone telephone) { 17 | this.id = id; 18 | this.price = price; 19 | this.product_id = product_id; 20 | this.ingredient_id = ingredient_id; 21 | this.email_address = email_address; 22 | this.telephone = telephone; 23 | } 24 | 25 | public Float getPrice() { 26 | return price; 27 | } 28 | 29 | public OrderId getId() { 30 | return id; 31 | } 32 | 33 | public ProductId productId() { 34 | return product_id; 35 | } 36 | 37 | public IngredientId ingredientId() { 38 | return ingredient_id; 39 | } 40 | 41 | public EmailAddress emailAddress() { 42 | return email_address; 43 | } 44 | 45 | public Telephone telephone() { 46 | return telephone; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/model/OrderId.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | import com.alg.order.common.AbstractId; 4 | 5 | public class OrderId extends AbstractId { 6 | 7 | public OrderId() { 8 | super(); 9 | // TODO Auto-generated constructor stub 10 | } 11 | 12 | public OrderId(String anId) { 13 | super(anId); 14 | // TODO Auto-generated constructor stub 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/model/Product.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | import com.alg.order.common.Entity; 4 | 5 | public class Product implements Entity { 6 | private ProductId id; 7 | private String name; 8 | private ProductPrice price; 9 | 10 | public Product() { 11 | 12 | } 13 | 14 | public Product(ProductId id, String name, ProductPrice price) { 15 | super(); 16 | this.id = id; 17 | setName(name); 18 | this.price = price; 19 | } 20 | 21 | private void setName(String name) { 22 | this.name = name; 23 | } 24 | 25 | public String getName() { 26 | return this.name; 27 | } 28 | 29 | public ProductId getId() { 30 | return id; 31 | } 32 | 33 | public ProductPrice getPrice() { 34 | return price; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/model/ProductId.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | import com.alg.order.common.AbstractId; 4 | import com.alg.order.common.ValueObject; 5 | 6 | public class ProductId extends AbstractId implements ValueObject { 7 | 8 | public ProductId() { 9 | super(); 10 | // TODO Auto-generated constructor stub 11 | } 12 | 13 | public ProductId(String anId) { 14 | super(anId); 15 | // TODO Auto-generated constructor stub 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/model/ProductPrice.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | import com.alg.order.common.AssertionConcern; 4 | import com.alg.order.common.ValueObject; 5 | 6 | public class ProductPrice extends AssertionConcern implements ValueObject { 7 | private Float price; 8 | 9 | public ProductPrice(Float price) { 10 | super(); 11 | 12 | this.setPrice(price); 13 | } 14 | 15 | private void setPrice(Float aPrice) { 16 | this.assertArgumentNotNull(aPrice, "Product price is required."); 17 | 18 | this.price = aPrice; 19 | } 20 | 21 | public Float price() { 22 | return price; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/model/Telephone.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.model; 2 | 3 | import com.alg.order.common.AssertionConcern; 4 | import com.alg.order.common.ValueObject; 5 | 6 | public final class Telephone extends AssertionConcern implements ValueObject { 7 | private String number; 8 | 9 | public Telephone(String aNumber) { 10 | this(); 11 | 12 | this.setNumber(aNumber); 13 | } 14 | 15 | public String number() { 16 | return this.number; 17 | } 18 | 19 | @Override 20 | public boolean equals(Object anObject) { 21 | boolean equalObjects = false; 22 | 23 | if (anObject != null && this.getClass() == anObject.getClass()) { 24 | Telephone typedObject = (Telephone) anObject; 25 | equalObjects = this.number().equals(typedObject.number()); 26 | } 27 | 28 | return equalObjects; 29 | } 30 | 31 | @Override 32 | public int hashCode() { 33 | int hashCodeValue = +(35137 * 239) + this.number().hashCode(); 34 | 35 | return hashCodeValue; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return "Telephone [number=" + number + "]"; 41 | } 42 | 43 | public Telephone() { 44 | super(); 45 | } 46 | 47 | private void setNumber(String aNumber) { 48 | this.assertArgumentNotEmpty(aNumber, "Telephone number is required."); 49 | this.assertArgumentLength(aNumber, 5, 20, 50 | "Telephone number may not be more than 20 characters."); 51 | /* this.assertArgumentTrue(Pattern.matches( 52 | "((\\(\\d{3}\\))|(\\d{3}-))\\d{3}-\\d{4}", aNumber), 53 | "Telephone number or its format is invalid.");*/ 54 | 55 | this.number = aNumber; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/repository/AbstractRepository.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.repository; 2 | 3 | import java.sql.Connection; 4 | import java.sql.DriverManager; 5 | import java.sql.SQLException; 6 | import java.util.Properties; 7 | 8 | import com.alg.order.common.Entity; 9 | 10 | public abstract class AbstractRepository implements IRepository { 11 | protected Connection connection; 12 | 13 | protected void connect() throws SQLException { 14 | String url = "jdbc:mysql://localhost:3306/test"; 15 | String user = "algo"; 16 | String password = "algo"; 17 | // Load the Oracle JDBC driver 18 | try { 19 | Class.forName("com.mysql.jdbc.Driver"); 20 | } catch (ClassNotFoundException e) { 21 | e.printStackTrace(); 22 | } 23 | 24 | Properties properties = new Properties(); 25 | properties.setProperty("user", user); 26 | properties.setProperty("password", password); 27 | properties.setProperty("useSSL", "false"); 28 | properties.setProperty("autoReconnect", "true"); 29 | 30 | // Connect to the database 31 | connection = DriverManager.getConnection(url, properties); 32 | } 33 | 34 | protected void close() throws SQLException { 35 | connection.close(); 36 | } 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/repository/IRepository.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.repository; 2 | 3 | import java.util.List; 4 | 5 | import com.alg.order.common.Entity; 6 | import com.alg.order.repository.specifications.ISqlSpecification; 7 | 8 | public interface IRepository { 9 | 10 | List query(ISqlSpecification specification) throws Exception; 11 | 12 | void save(E entity) throws Exception; 13 | 14 | boolean delete(E entity) throws Exception; 15 | 16 | boolean update(E entity) throws Exception; 17 | 18 | List findAll() throws Exception; 19 | } 20 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/repository/IngredientRepository.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.repository; 2 | 3 | import java.sql.PreparedStatement; 4 | import java.sql.ResultSet; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import com.alg.order.model.Ingredient; 9 | import com.alg.order.model.IngredientColor; 10 | import com.alg.order.model.IngredientId; 11 | import com.alg.order.model.IngredientPrice; 12 | import com.alg.order.repository.specifications.ISqlSpecification; 13 | 14 | public class IngredientRepository extends AbstractRepository { 15 | 16 | @Override 17 | public void save(Ingredient entity) throws Exception { 18 | connect(); 19 | PreparedStatement pstmt = connection 20 | .prepareStatement("insert into INGREDIENTS " 21 | + "(INGREDIENT_ID, INGREDIENT_NAME, PRICE, COLOR)" 22 | + "values (?, ?, ?, ?)"); 23 | pstmt.setString(0, entity.getId().id()); 24 | pstmt.setString(1, entity.getName()); 25 | pstmt.setFloat(2, entity.getPrice().price()); 26 | pstmt.setString(3, entity.getColor().color()); 27 | pstmt.execute(); 28 | pstmt.close(); 29 | close(); 30 | } 31 | 32 | @Override 33 | public boolean delete(Ingredient entity) throws Exception { 34 | connect(); 35 | PreparedStatement pstmt = connection 36 | .prepareStatement("DELETE FROM INGREDIENTS WHERE PRODUCT_ID = ?"); 37 | pstmt.setString(0, entity.getId().id()); 38 | boolean res = pstmt.executeUpdate() > 0; 39 | pstmt.close(); 40 | close(); 41 | return res; 42 | } 43 | 44 | @Override 45 | public List findAll() throws Exception { 46 | ArrayList all = new ArrayList(); 47 | connect(); 48 | PreparedStatement pstmt = connection 49 | .prepareStatement("SELECT * FROM INGREDIENTS"); 50 | ResultSet rs = pstmt.executeQuery(); 51 | while (rs.next()) { 52 | Ingredient p = new Ingredient(new IngredientId( 53 | rs.getString("INGREDIENT_ID")), 54 | rs.getString("INGREDIENT_NAME"), new IngredientPrice( 55 | rs.getFloat("PRICE")), new IngredientColor( 56 | rs.getString("COLOR"))); 57 | all.add(p); 58 | } 59 | rs.close(); 60 | pstmt.close(); 61 | close(); 62 | return all; 63 | } 64 | 65 | @Override 66 | public boolean update(Ingredient entity) throws Exception { 67 | connect(); 68 | PreparedStatement pstmt = connection 69 | .prepareStatement("UPDATE INGREDIENTS SET INGREDIENT_ID = ?, INGREDIENT_NAME = ?, PRICE = ?, COLOR=?)"); 70 | pstmt.setString(0, entity.getId().id()); 71 | pstmt.setString(1, entity.getName()); 72 | pstmt.setFloat(2, entity.getPrice().price()); 73 | pstmt.setString(3, entity.getColor().color()); 74 | boolean res = pstmt.executeUpdate() > 0; 75 | pstmt.close(); 76 | close(); 77 | return res; 78 | } 79 | 80 | @Override 81 | public List query(ISqlSpecification specification) 82 | throws Exception { 83 | ArrayList all = new ArrayList(); 84 | connect(); 85 | PreparedStatement pstmt = connection.prepareStatement(specification 86 | .toSqlClauses()); 87 | ResultSet rs = pstmt.executeQuery(); 88 | while (rs.next()) { 89 | Ingredient p = new Ingredient(new IngredientId( 90 | rs.getString("INGREDIENT_ID")), 91 | rs.getString("INGREDIENT_NAME"), new IngredientPrice( 92 | rs.getFloat("PRICE")), new IngredientColor( 93 | rs.getString("COLOR"))); 94 | all.add(p); 95 | } 96 | rs.close(); 97 | pstmt.close(); 98 | close(); 99 | return all; 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/repository/OrderRepository.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.repository; 2 | 3 | import java.sql.PreparedStatement; 4 | import java.sql.ResultSet; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import com.alg.order.model.EmailAddress; 9 | import com.alg.order.model.IngredientId; 10 | import com.alg.order.model.Order; 11 | import com.alg.order.model.OrderId; 12 | import com.alg.order.model.ProductId; 13 | import com.alg.order.model.Telephone; 14 | import com.alg.order.repository.specifications.ISqlSpecification; 15 | 16 | public class OrderRepository extends AbstractRepository { 17 | 18 | @Override 19 | public void save(Order entity) throws Exception { 20 | connect(); 21 | PreparedStatement pstmt = connection 22 | .prepareStatement("INSERT INTO ORDERS " 23 | + "(ORDER_ID, PRICE, PRODUCT_ID, INGREDIENT_ID, EMAIL, TEL)" 24 | + "values (?, ?, ?, ?, ?, ?)"); 25 | pstmt.setString(1, entity.getId().id()); 26 | pstmt.setFloat(2, entity.getPrice()); 27 | pstmt.setString(3, entity.productId().id()); 28 | pstmt.setString(4, entity.ingredientId().id()); 29 | pstmt.setString(5, entity.emailAddress().address()); 30 | pstmt.setString(6, entity.telephone().number()); 31 | pstmt.execute(); 32 | pstmt.close(); 33 | connection.close(); 34 | } 35 | 36 | @Override 37 | public boolean delete(Order entity) throws Exception { 38 | connect(); 39 | PreparedStatement pstmt = connection 40 | .prepareStatement("DELETE FROM ORDERS WHERE ORDER_ID = ?"); 41 | pstmt.setString(0, entity.getId().id()); 42 | boolean res = pstmt.executeUpdate() > 0; 43 | pstmt.close(); 44 | close(); 45 | return res; 46 | } 47 | 48 | @Override 49 | public List findAll() throws Exception { 50 | ArrayList all = new ArrayList(); 51 | connect(); 52 | PreparedStatement pstmt = connection 53 | .prepareStatement("SELECT * FROM ORDERS ORDER BY ORDER_ID DESC"); 54 | ResultSet rs = pstmt.executeQuery(); 55 | while (rs.next()) { 56 | Order o = new Order(new OrderId(rs.getString("ORDER_ID")), 57 | rs.getFloat("PRICE"), new ProductId( 58 | rs.getString("PRODUCT_ID")), new IngredientId( 59 | rs.getString("INGREDIENT_ID")), new EmailAddress( 60 | rs.getString("EMAIL")), new Telephone( 61 | rs.getString("TEL"))); 62 | all.add(o); 63 | } 64 | rs.close(); 65 | pstmt.close(); 66 | close(); 67 | return all; 68 | } 69 | 70 | @Override 71 | public boolean update(Order entity) throws Exception { 72 | connect(); 73 | PreparedStatement pstmt = connection 74 | .prepareStatement("UPDATE ORDERS SET ORDER_ID = ?, PRICE = ?)"); 75 | pstmt.setString(0, entity.getId().id()); 76 | pstmt.setFloat(1, entity.getPrice()); 77 | boolean res = pstmt.executeUpdate() > 0; 78 | pstmt.close(); 79 | close(); 80 | return res; 81 | 82 | } 83 | 84 | @Override 85 | public List query(ISqlSpecification specification) throws Exception { 86 | ArrayList all = new ArrayList(); 87 | connect(); 88 | PreparedStatement pstmt = connection.prepareStatement(specification 89 | .toSqlClauses()); 90 | ResultSet rs = pstmt.executeQuery(); 91 | while (rs.next()) { 92 | Order o = new Order(new OrderId(rs.getString("ORDER_ID")), 93 | rs.getFloat("PRICE"), new ProductId( 94 | rs.getString("PRODUCT_ID")), new IngredientId( 95 | rs.getString("INGREDIENT_ID")), new EmailAddress( 96 | rs.getString("EMAIL")), new Telephone( 97 | rs.getString("TEL"))); 98 | all.add(o); 99 | } 100 | rs.close(); 101 | pstmt.close(); 102 | close(); 103 | return all; 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/repository/ProductRepository.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.repository; 2 | 3 | import java.sql.PreparedStatement; 4 | import java.sql.ResultSet; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import com.alg.order.model.Product; 9 | import com.alg.order.model.ProductId; 10 | import com.alg.order.model.ProductPrice; 11 | import com.alg.order.repository.specifications.ISqlSpecification; 12 | 13 | public class ProductRepository extends AbstractRepository { 14 | 15 | @Override 16 | public void save(Product entity) throws Exception { 17 | connect(); 18 | PreparedStatement pstmt = connection 19 | .prepareStatement("INSERT INTO PRODUCTS " 20 | + "(PRODUCT_ID, PRODUCT_NAME, PRICE)" 21 | + "values (?, ?, ?)"); 22 | pstmt.setString(0, entity.getId().id()); 23 | pstmt.setString(1, entity.getName()); 24 | pstmt.setFloat(2, entity.getPrice().price()); 25 | pstmt.execute(); 26 | pstmt.close(); 27 | close(); 28 | } 29 | 30 | @Override 31 | public boolean delete(Product entity) throws Exception { 32 | connect(); 33 | PreparedStatement pstmt = connection 34 | .prepareStatement("DELETE FROM PRODUCTS WHERE PRODUCT_ID = ?"); 35 | pstmt.setString(0, entity.getId().id()); 36 | boolean res = pstmt.executeUpdate() > 0; 37 | pstmt.close(); 38 | close(); 39 | return res; 40 | 41 | } 42 | 43 | @Override 44 | public List findAll() throws Exception { 45 | ArrayList all = new ArrayList(); 46 | connect(); 47 | PreparedStatement pstmt = connection 48 | .prepareStatement("SELECT * FROM PRODUCTS"); 49 | ResultSet rs = pstmt.executeQuery(); 50 | while (rs.next()) { 51 | Product p = new Product(new ProductId(rs.getString("PRODUCT_ID")), 52 | rs.getString("PRODUCT_NAME"), new ProductPrice( 53 | rs.getFloat("PRICE"))); 54 | all.add(p); 55 | } 56 | //System.out.println(all); 57 | rs.close(); 58 | pstmt.close(); 59 | close(); 60 | return all; 61 | } 62 | 63 | @Override 64 | public boolean update(Product entity) throws Exception { 65 | connect(); 66 | PreparedStatement pstmt = connection 67 | .prepareStatement("UPDATE PRODUCTS SET PRODUCT_ID = ?, PRODUCT_NAME = ?, PRICE = ?)"); 68 | pstmt.setString(0, entity.getId().id()); 69 | pstmt.setString(1, entity.getName()); 70 | pstmt.setFloat(2, entity.getPrice().price()); 71 | boolean res = pstmt.executeUpdate() > 0; 72 | pstmt.close(); 73 | close(); 74 | return res; 75 | 76 | } 77 | 78 | @Override 79 | public List query(ISqlSpecification specification) 80 | throws Exception { 81 | ArrayList all = new ArrayList(); 82 | connect(); 83 | PreparedStatement pstmt = connection.prepareStatement(specification 84 | .toSqlClauses()); 85 | ResultSet rs = pstmt.executeQuery(); 86 | while (rs.next()) { 87 | Product p = new Product(new ProductId(rs.getString("PRODUCT_ID")), 88 | rs.getString("PRODUCT_NAME"), new ProductPrice( 89 | rs.getFloat("PRICE"))); 90 | all.add(p); 91 | } 92 | rs.close(); 93 | pstmt.close(); 94 | close(); 95 | return all; 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/repository/specifications/ISqlSpecification.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.repository.specifications; 2 | 3 | public interface ISqlSpecification { 4 | String toSqlClauses(); 5 | } 6 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/repository/specifications/IngredeintSpecificationById.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.repository.specifications; 2 | 3 | import com.alg.order.model.IngredientId; 4 | 5 | public class IngredeintSpecificationById implements ISqlSpecification { 6 | private IngredientId id; 7 | 8 | public IngredeintSpecificationById(IngredientId id) { 9 | super(); 10 | this.id = id; 11 | } 12 | 13 | @Override 14 | public String toSqlClauses() { 15 | return String.format("SELECT * FROM INGREDIENTS WHERE INGREDIENT_ID = %s", id.id()); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/repository/specifications/OrderSpecificationById.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.repository.specifications; 2 | 3 | import com.alg.order.model.OrderId; 4 | 5 | public class OrderSpecificationById implements ISqlSpecification { 6 | private OrderId id; 7 | 8 | public OrderSpecificationById(OrderId id) { 9 | super(); 10 | this.id = id; 11 | } 12 | 13 | @Override 14 | public String toSqlClauses() { 15 | return String.format("SELECT * FROM ORDERS WHERE ORDER_ID = %s", id.id()); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/repository/specifications/ProductSpecificationById.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.repository.specifications; 2 | 3 | import com.alg.order.model.ProductId; 4 | 5 | public class ProductSpecificationById implements ISqlSpecification { 6 | private ProductId id; 7 | 8 | public ProductSpecificationById(ProductId id) { 9 | super(); 10 | this.id = id; 11 | } 12 | 13 | @Override 14 | public String toSqlClauses() { 15 | return String.format("SELECT * FROM PRODUCTS WHERE PRODUCT_ID = %s", id.id()); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/repository/specifications/ProductSpecificationByName.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.repository.specifications; 2 | 3 | public class ProductSpecificationByName implements ISqlSpecification { 4 | private String name; 5 | 6 | public ProductSpecificationByName(String name) { 7 | super(); 8 | this.name = name; 9 | } 10 | 11 | @Override 12 | public String toSqlClauses() { 13 | return String.format("SELECT * FROM PRODUCTS WHERE PRODUCT_NAME = %s", name); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/repository/specifications/ProductSpecificationByPriceRange.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.repository.specifications; 2 | 3 | public class ProductSpecificationByPriceRange implements ISqlSpecification { 4 | private float min_price; 5 | private float max_price; 6 | 7 | public ProductSpecificationByPriceRange(float min_price, float max_price) { 8 | super(); 9 | this.min_price = min_price; 10 | this.max_price = max_price; 11 | } 12 | 13 | @Override 14 | public String toSqlClauses() { 15 | return String.format("SELECT * FROM PRODUCTS WHERE PRICE BETWEEN %s AND %s", min_price, max_price); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/service/IOrderService.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.service; 2 | 3 | import java.util.List; 4 | 5 | import com.alg.order.model.OrderId; 6 | 7 | public interface IOrderService { 8 | List getAllOrderSummaries(); 9 | 10 | OrderSummaryDTO getOrderSummary(OrderId order_id); 11 | 12 | List getAllProducts(); 13 | 14 | List getAllIngredients(); 15 | 16 | void addOrder(OrderDTO orderdto); 17 | } 18 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/service/IngredientDTO.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.service; 2 | 3 | import com.alg.order.model.IngredientId; 4 | 5 | public class IngredientDTO { 6 | private String name; 7 | private IngredientId id; 8 | 9 | public IngredientDTO(String name, IngredientId id) { 10 | super(); 11 | this.name = name; 12 | this.id = id; 13 | } 14 | 15 | public String getName() { 16 | return name; 17 | } 18 | 19 | public void setName(String name) { 20 | this.name = name; 21 | } 22 | 23 | public IngredientId getId() { 24 | return id; 25 | } 26 | 27 | public void setId(IngredientId id) { 28 | this.id = id; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/service/OrderDTO.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.service; 2 | 3 | public class OrderDTO { 4 | private String pid; 5 | private String iid; 6 | private String tel; 7 | private String email; 8 | 9 | public OrderDTO() { 10 | 11 | } 12 | 13 | public OrderDTO(String pid, String iid) { 14 | super(); 15 | this.pid = pid; 16 | this.iid = iid; 17 | } 18 | 19 | public String getPid() { 20 | return pid; 21 | } 22 | 23 | public void setPid(String pid) { 24 | this.pid = pid; 25 | } 26 | 27 | public String getIid() { 28 | return iid; 29 | } 30 | 31 | public void setIid(String iid) { 32 | this.iid = iid; 33 | } 34 | 35 | public String getTel() { 36 | return tel; 37 | } 38 | 39 | public void setTel(String tel) { 40 | this.tel = tel; 41 | } 42 | 43 | public String getEmail() { 44 | return email; 45 | } 46 | 47 | public void setEmail(String email) { 48 | this.email = email; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/service/OrderSummaryDTO.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.service; 2 | 3 | import com.alg.order.model.OrderId; 4 | 5 | public class OrderSummaryDTO { 6 | private OrderId order_id; 7 | private String product_name; 8 | private String ingredient_name; 9 | private Float total_price; 10 | 11 | public OrderSummaryDTO(OrderId order_id, String product_name, String ingredient_name, 12 | Float total_price) { 13 | super(); 14 | this.order_id = order_id; 15 | this.product_name = product_name; 16 | this.ingredient_name = ingredient_name; 17 | this.total_price = total_price; 18 | } 19 | 20 | public String getProduct_name() { 21 | return product_name; 22 | } 23 | 24 | public String getIngredient_name() { 25 | return ingredient_name; 26 | } 27 | 28 | public Float getTotal_price() { 29 | return total_price; 30 | } 31 | 32 | public OrderId getOrder_id() { 33 | return order_id; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/service/ProductDTO.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.service; 2 | 3 | import com.alg.order.model.ProductId; 4 | 5 | public class ProductDTO { 6 | private String name; 7 | private ProductId id; 8 | 9 | public ProductDTO(String name, ProductId id) { 10 | super(); 11 | this.name = name; 12 | this.id = id; 13 | } 14 | 15 | public String getName() { 16 | return name; 17 | } 18 | 19 | public void setName(String name) { 20 | this.name = name; 21 | } 22 | 23 | public ProductId getId() { 24 | return id; 25 | } 26 | 27 | public void setId(ProductId id) { 28 | this.id = id; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /2019-aug/4.domain layer patterns/src/com/alg/order/ui/Test.java: -------------------------------------------------------------------------------- 1 | package com.alg.order.ui; 2 | 3 | import java.awt.Dimension; 4 | import java.awt.Toolkit; 5 | 6 | import javax.swing.JFrame; 7 | import javax.swing.WindowConstants; 8 | 9 | import com.alg.order.repository.IngredientRepository; 10 | import com.alg.order.repository.OrderRepository; 11 | import com.alg.order.repository.ProductRepository; 12 | import com.alg.order.service.OrderServiceImpl; 13 | 14 | public class Test { 15 | 16 | public static void main(String[] args) { 17 | JFrame frame; 18 | frame = new JFrame("Simple Ordering Application"); 19 | ProductRepository prepository = new ProductRepository(); 20 | IngredientRepository irepository = new IngredientRepository(); 21 | OrderRepository orepository = new OrderRepository(); 22 | frame.setContentPane(new ContentPanel(new OrderServiceImpl(prepository, irepository, 23 | orepository))); 24 | frame.pack(); 25 | Dimension frameDim = new Dimension(500, 500); 26 | Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); 27 | frame.setLocation(screenSize.width / 2 - frameDim.width / 2, 28 | screenSize.height / 2 - frameDim.height / 2); 29 | frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 30 | frame.setSize(frameDim); 31 | frame.setVisible(true); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/1.synchronization problems/src/threading/Memory.java: -------------------------------------------------------------------------------- 1 | package threading; 2 | 3 | class Dummy { 4 | private int count = 0; 5 | private boolean countReady = false; 6 | public void update() { 7 | count = 10; 8 | countReady = true; 9 | } 10 | public int get() { 11 | return count; 12 | } 13 | public boolean isReady() { 14 | return countReady; 15 | } 16 | } 17 | 18 | class DummyThread1 extends Thread { 19 | private Dummy dummy; 20 | 21 | public DummyThread1(Dummy dummy) { 22 | this.dummy = dummy; 23 | } 24 | 25 | public void run() { 26 | dummy.update(); 27 | } 28 | } 29 | 30 | class DummyThread2 extends Thread { 31 | private Dummy dummy; 32 | 33 | public DummyThread2(Dummy dummy) { 34 | this.dummy = dummy; 35 | } 36 | 37 | public void run() { 38 | if(dummy.isReady()) 39 | System.out.println("The counter value:" + dummy.get()); 40 | else 41 | System.out.println("Dont know counter value"); 42 | } 43 | } 44 | 45 | public class Memory { 46 | public static void main(String[] args) throws Exception { 47 | Dummy dummy = new Dummy(); 48 | DummyThread1 dt1 = new DummyThread1(dummy); 49 | DummyThread2 dt2 = new DummyThread2(dummy); 50 | dt1.start(); 51 | dt2.start(); 52 | dt1.join(); 53 | dt2.join(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/1.synchronization problems/src/threading/RaceCondition.java: -------------------------------------------------------------------------------- 1 | package threading; 2 | 3 | class Counter { 4 | private int count = 0; 5 | public void increment() { 6 | ++count; 7 | } 8 | public int get() { 9 | return count; 10 | } 11 | } 12 | 13 | class CountingThread extends Thread { 14 | private Counter counter; 15 | 16 | public CountingThread(Counter counter) { 17 | this.counter = counter; 18 | } 19 | 20 | public void run() { 21 | for(int i = 0; i < 10000; ++i) 22 | counter.increment(); 23 | } 24 | } 25 | 26 | public class RaceCondition { 27 | 28 | public static void main(String[] args) throws Exception { 29 | Counter counter = new Counter(); 30 | CountingThread ct1 = new CountingThread(counter); 31 | CountingThread ct2 = new CountingThread(counter); 32 | ct1.start(); 33 | ct2.start(); 34 | ct1.join(); 35 | ct2.join(); 36 | System.out.println(counter.get()); 37 | 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/1.synchronization problems/src/threading/RaceConditionSol1.java: -------------------------------------------------------------------------------- 1 | package threading; 2 | 3 | class Counter1 { 4 | private int count = 0; 5 | public void increment() { 6 | ++count; 7 | } 8 | public int get() { 9 | return count; 10 | } 11 | } 12 | 13 | class CountingThread1 extends Thread { 14 | private Counter1 counter; 15 | 16 | public CountingThread1(Counter1 counter) { 17 | this.counter = counter; 18 | } 19 | 20 | public void run() { 21 | for(int i = 0; i < 10000; ++i) 22 | counter.increment(); 23 | } 24 | } 25 | 26 | public class RaceConditionSol1 { 27 | 28 | public static void main(String[] args) throws Exception { 29 | Counter1 counter = new Counter1(); 30 | CountingThread1 ct1 = new CountingThread1(counter); 31 | CountingThread1 ct2 = new CountingThread1(counter); 32 | ct1.start(); 33 | ct2.start(); 34 | ct1.join(); 35 | ct2.join(); 36 | System.out.println(counter.get()); 37 | 38 | } 39 | 40 | } 41 | 42 | /* 43 | Intrinsic locks are convenient but limited. 44 | � There is no way to interrupt a thread that�s blocked as a result of trying 45 | to acquire an intrinsic lock. 46 | � There is no way to time out while trying to acquire an intrinsic lock. 47 | � There�s exactly one way to acquire an intrinsic lock: a synchronized block 48 | */ 49 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/1.synchronization problems/src/threading/Test.java: -------------------------------------------------------------------------------- 1 | package threading; 2 | 3 | import java.util.concurrent.ArrayBlockingQueue; 4 | import java.util.concurrent.BlockingQueue; 5 | import java.util.concurrent.LinkedBlockingQueue; 6 | 7 | public class Test { 8 | 9 | public static void main(String[] args) throws Exception { 10 | BlockingQueue queue = new LinkedBlockingQueue(3); 11 | for(int i = 0; i < 3; ++i) 12 | queue.put(i); 13 | queue.put(10); 14 | System.out.println(queue); 15 | 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/2.wiki-wordcount/src/com/alg/concurrency/threading/wordcount1/sequential/Page.java: -------------------------------------------------------------------------------- 1 | package com.alg.concurrency.threading.wordcount1.sequential; 2 | 3 | class Page { 4 | private String title; 5 | private String text; 6 | 7 | public Page(String title, String text) { 8 | this.title = title; 9 | this.text = text; 10 | } 11 | 12 | public String getTitle() { 13 | return title; 14 | } 15 | 16 | public String getText() { 17 | return text; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/2.wiki-wordcount/src/com/alg/concurrency/threading/wordcount1/sequential/Pages.java: -------------------------------------------------------------------------------- 1 | package com.alg.concurrency.threading.wordcount1.sequential; 2 | 3 | import java.io.FileInputStream; 4 | import java.util.Iterator; 5 | import java.util.NoSuchElementException; 6 | 7 | import javax.xml.stream.XMLEventReader; 8 | import javax.xml.stream.XMLInputFactory; 9 | import javax.xml.stream.events.XMLEvent; 10 | 11 | class Pages implements Iterable { 12 | 13 | private final int maxPages; 14 | private final String fileName; 15 | 16 | public Pages(int maxPages, String fileName) { 17 | this.maxPages = maxPages; 18 | this.fileName = fileName; 19 | } 20 | 21 | private class PageIterator implements Iterator { 22 | 23 | private XMLEventReader reader; 24 | private int remainingPages; 25 | 26 | public PageIterator() throws Exception { 27 | remainingPages = maxPages; 28 | reader = XMLInputFactory.newInstance().createXMLEventReader(new FileInputStream(fileName)); 29 | } 30 | 31 | public boolean hasNext() { 32 | return remainingPages > 0; 33 | } 34 | 35 | public Page next() { 36 | try { 37 | XMLEvent event; 38 | String title = ""; 39 | String text = ""; 40 | while (true) { 41 | event = reader.nextEvent(); 42 | // System.out.println(event); 43 | if (event.isStartElement()) { 44 | if (event.asStartElement().getName().getLocalPart().equals("page")) { 45 | while (true) { 46 | event = reader.nextEvent(); 47 | if (event.isStartElement()) { 48 | String name = event.asStartElement().getName().getLocalPart(); 49 | if (name.equals("title")) 50 | title = reader.getElementText(); 51 | else if (name.equals("text")) 52 | text = reader.getElementText(); 53 | } else if (event.isEndElement()) { 54 | if (event.asEndElement().getName().getLocalPart().equals("page")) { 55 | --remainingPages; 56 | return new Page(title, text); 57 | } 58 | } 59 | } 60 | } 61 | } 62 | } 63 | } catch (Exception e) { 64 | throw new NoSuchElementException(); 65 | } 66 | 67 | } 68 | 69 | public void remove() { 70 | throw new UnsupportedOperationException(); 71 | } 72 | } 73 | 74 | public Iterator iterator() { 75 | try { 76 | return new PageIterator(); 77 | } catch (Exception e) { 78 | throw new RuntimeException(e); 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/2.wiki-wordcount/src/com/alg/concurrency/threading/wordcount1/sequential/Test.java: -------------------------------------------------------------------------------- 1 | package com.alg.concurrency.threading.wordcount1.sequential; 2 | 3 | import java.util.HashMap; 4 | 5 | public class Test { 6 | private static HashMap counts = new HashMap(); 7 | 8 | private static void countWord(String word) { 9 | Integer currentCount = counts.get(word); 10 | if (currentCount == null) 11 | counts.put(word, 1); 12 | else 13 | counts.put(word, currentCount + 1); 14 | } 15 | 16 | private static void parseAndCountWords(int maxPages, String file) { 17 | Iterable pages = new Pages(maxPages, file); 18 | for (Page page : pages) { 19 | Iterable words = new Words(page.getText()); 20 | for (String word : words) 21 | countWord(word); 22 | } 23 | } 24 | 25 | public static void main(String[] args) throws Exception { 26 | long start = System.currentTimeMillis(); 27 | parseAndCountWords(Integer.parseInt(args[0]), args[1]); 28 | long end = System.currentTimeMillis(); 29 | System.out.println("Elapsed time: " + (end - start) / 1000.0 + "s"); 30 | 31 | // for (Map.Entry e : counts.entrySet()) { 32 | // System.out.println(e); 33 | // } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/2.wiki-wordcount/src/com/alg/concurrency/threading/wordcount1/sequential/Words.java: -------------------------------------------------------------------------------- 1 | package com.alg.concurrency.threading.wordcount1.sequential; 2 | 3 | import java.text.BreakIterator; 4 | import java.util.Iterator; 5 | 6 | public class Words implements Iterable { 7 | 8 | private final String text; 9 | 10 | public Words(String text) { 11 | this.text = text; 12 | } 13 | 14 | private class WordIterator implements Iterator { 15 | 16 | private BreakIterator wordBoundary; 17 | private int start; 18 | private int end; 19 | 20 | public WordIterator() { 21 | wordBoundary = BreakIterator.getWordInstance(); 22 | wordBoundary.setText(text); 23 | start = wordBoundary.first(); 24 | end = wordBoundary.next(); 25 | } 26 | 27 | public boolean hasNext() { return end != BreakIterator.DONE; } 28 | 29 | public String next() { 30 | String s = text.substring(start, end); 31 | start = end; 32 | end = wordBoundary.next(); 33 | return s; 34 | } 35 | 36 | public void remove() { throw new UnsupportedOperationException(); } 37 | } 38 | 39 | public Iterator iterator() { 40 | return new WordIterator(); 41 | } 42 | } -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/2.wiki-wordcount/src/com/alg/concurrency/threading/wordcount2/concurrent/Page.java: -------------------------------------------------------------------------------- 1 | package com.alg.concurrency.threading.wordcount2.concurrent; 2 | 3 | class Page { 4 | private String title; 5 | private String text; 6 | 7 | public Page(String title, String text) { 8 | this.title = title; 9 | this.text = text; 10 | } 11 | 12 | public String getTitle() { 13 | return title; 14 | } 15 | 16 | public String getText() { 17 | return text; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/2.wiki-wordcount/src/com/alg/concurrency/threading/wordcount2/concurrent/Pages.java: -------------------------------------------------------------------------------- 1 | package com.alg.concurrency.threading.wordcount2.concurrent; 2 | 3 | import java.io.FileInputStream; 4 | import java.util.Iterator; 5 | import java.util.NoSuchElementException; 6 | 7 | import javax.xml.stream.XMLEventReader; 8 | import javax.xml.stream.XMLInputFactory; 9 | import javax.xml.stream.events.XMLEvent; 10 | 11 | class Pages implements Iterable { 12 | 13 | private final int maxPages; 14 | private final String fileName; 15 | 16 | public Pages(int maxPages, String fileName) { 17 | this.maxPages = maxPages; 18 | this.fileName = fileName; 19 | } 20 | 21 | private class PageIterator implements Iterator { 22 | 23 | private XMLEventReader reader; 24 | private int remainingPages; 25 | 26 | public PageIterator() throws Exception { 27 | remainingPages = maxPages; 28 | reader = XMLInputFactory.newInstance().createXMLEventReader(new FileInputStream(fileName)); 29 | } 30 | 31 | public boolean hasNext() { 32 | return remainingPages > 0; 33 | } 34 | 35 | public Page next() { 36 | try { 37 | XMLEvent event; 38 | String title = ""; 39 | String text = ""; 40 | while (true) { 41 | event = reader.nextEvent(); 42 | // System.out.println(event); 43 | if (event.isStartElement()) { 44 | if (event.asStartElement().getName().getLocalPart().equals("page")) { 45 | while (true) { 46 | event = reader.nextEvent(); 47 | if (event.isStartElement()) { 48 | String name = event.asStartElement().getName().getLocalPart(); 49 | if (name.equals("title")) 50 | title = reader.getElementText(); 51 | else if (name.equals("text")) 52 | text = reader.getElementText(); 53 | } else if (event.isEndElement()) { 54 | if (event.asEndElement().getName().getLocalPart().equals("page")) { 55 | --remainingPages; 56 | return new Page(title, text); 57 | } 58 | } 59 | } 60 | } 61 | } 62 | } 63 | } catch (Exception e) { 64 | throw new NoSuchElementException(); 65 | } 66 | 67 | } 68 | 69 | public void remove() { 70 | throw new UnsupportedOperationException(); 71 | } 72 | } 73 | 74 | public Iterator iterator() { 75 | try { 76 | return new PageIterator(); 77 | } catch (Exception e) { 78 | throw new RuntimeException(e); 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/2.wiki-wordcount/src/com/alg/concurrency/threading/wordcount2/concurrent/Parser.java: -------------------------------------------------------------------------------- 1 | package com.alg.concurrency.threading.wordcount2.concurrent; 2 | 3 | import java.util.Iterator; 4 | import java.util.concurrent.BlockingQueue; 5 | 6 | class Parser implements Runnable { 7 | private BlockingQueue queue; 8 | private int maxPages; 9 | private String file; 10 | 11 | public Parser(BlockingQueue queue, int maxPages, String file) { 12 | this.queue = queue; 13 | this.maxPages = maxPages; 14 | this.file = file; 15 | } 16 | 17 | public void run() { 18 | try { 19 | Iterator pages = new Pages(maxPages, file).iterator(); 20 | while(pages.hasNext()) { 21 | Page page = pages.next(); 22 | queue.put(page); 23 | //System.out.println("parser:" + page.getTitle()); 24 | } 25 | } catch (Exception e) { 26 | e.printStackTrace(); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/2.wiki-wordcount/src/com/alg/concurrency/threading/wordcount2/concurrent/Test.java: -------------------------------------------------------------------------------- 1 | package com.alg.concurrency.threading.wordcount2.concurrent; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import java.util.concurrent.ArrayBlockingQueue; 6 | 7 | public class Test { 8 | 9 | public static void main(String[] args) throws Exception { 10 | ArrayBlockingQueue queue = new ArrayBlockingQueue(1000); 11 | Map counts = new HashMap(); 12 | 13 | Thread counter = new Thread(new WordCounter(queue, counts)); 14 | Thread parser = new Thread(new Parser(queue, Integer.parseInt(args[0]), args[1])); 15 | long start = System.currentTimeMillis(); 16 | counter.start(); 17 | parser.start(); 18 | parser.join(); 19 | queue.put(new Page("terminate", null)); 20 | counter.join(); 21 | long end = System.currentTimeMillis(); 22 | System.out.println("Elapsed time: " + (end - start) / 1000.0 + "s"); 23 | 24 | // for (Map.Entry e: counts.entrySet()) { 25 | // System.out.println(e); 26 | // } 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/2.wiki-wordcount/src/com/alg/concurrency/threading/wordcount2/concurrent/WordCounter.java: -------------------------------------------------------------------------------- 1 | package com.alg.concurrency.threading.wordcount2.concurrent; 2 | 3 | import java.util.Map; 4 | import java.util.concurrent.BlockingQueue; 5 | 6 | class WordCounter implements Runnable { 7 | private BlockingQueue queue; 8 | private Map counts; 9 | 10 | public WordCounter(BlockingQueue queue, Map counts) { 11 | this.queue = queue; 12 | this.counts = counts; 13 | } 14 | 15 | public void run() { 16 | try { 17 | while (true) { 18 | Page page = queue.take(); 19 | //System.out.println("counter:" +page.getTitle()); 20 | if (page.getTitle().equals("terminate")) 21 | break; 22 | Iterable words = new Words(page.getText()); 23 | for (String word : words) 24 | countWord(word); 25 | } 26 | } catch (Exception e) { 27 | e.printStackTrace(); 28 | } 29 | } 30 | 31 | private void countWord(String word) { 32 | Integer currentCount = counts.get(word); 33 | if (currentCount == null) 34 | counts.put(word, 1); 35 | else 36 | counts.put(word, currentCount + 1); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/2.wiki-wordcount/src/com/alg/concurrency/threading/wordcount2/concurrent/Words.java: -------------------------------------------------------------------------------- 1 | package com.alg.concurrency.threading.wordcount2.concurrent; 2 | 3 | import java.text.BreakIterator; 4 | import java.util.Iterator; 5 | 6 | public class Words implements Iterable { 7 | 8 | private final String text; 9 | 10 | public Words(String text) { 11 | this.text = text; 12 | } 13 | 14 | private class WordIterator implements Iterator { 15 | 16 | private BreakIterator wordBoundary; 17 | private int start; 18 | private int end; 19 | 20 | public WordIterator() { 21 | wordBoundary = BreakIterator.getWordInstance(); 22 | wordBoundary.setText(text); 23 | start = wordBoundary.first(); 24 | end = wordBoundary.next(); 25 | } 26 | 27 | public boolean hasNext() { return end != BreakIterator.DONE; } 28 | 29 | public String next() { 30 | String s = text.substring(start, end); 31 | start = end; 32 | end = wordBoundary.next(); 33 | return s; 34 | } 35 | 36 | public void remove() { throw new UnsupportedOperationException(); } 37 | } 38 | 39 | public Iterator iterator() { 40 | return new WordIterator(); 41 | } 42 | } -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/2.wiki-wordcount/src/com/alg/concurrency/threading/wordcount3/concurrent/Page.java: -------------------------------------------------------------------------------- 1 | package com.alg.concurrency.threading.wordcount3.concurrent; 2 | 3 | class Page { 4 | private String title; 5 | private String text; 6 | 7 | public Page(String title, String text) { 8 | this.title = title; 9 | this.text = text; 10 | } 11 | 12 | public String getTitle() { 13 | return title; 14 | } 15 | 16 | public String getText() { 17 | return text; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/2.wiki-wordcount/src/com/alg/concurrency/threading/wordcount3/concurrent/Pages.java: -------------------------------------------------------------------------------- 1 | package com.alg.concurrency.threading.wordcount3.concurrent; 2 | 3 | import java.io.FileInputStream; 4 | import java.util.Iterator; 5 | import java.util.NoSuchElementException; 6 | 7 | import javax.xml.stream.XMLEventReader; 8 | import javax.xml.stream.XMLInputFactory; 9 | import javax.xml.stream.events.XMLEvent; 10 | 11 | class Pages implements Iterable { 12 | 13 | private final int maxPages; 14 | private final String fileName; 15 | 16 | public Pages(int maxPages, String fileName) { 17 | this.maxPages = maxPages; 18 | this.fileName = fileName; 19 | } 20 | 21 | private class PageIterator implements Iterator { 22 | 23 | private XMLEventReader reader; 24 | private int remainingPages; 25 | 26 | public PageIterator() throws Exception { 27 | remainingPages = maxPages; 28 | reader = XMLInputFactory.newInstance().createXMLEventReader(new FileInputStream(fileName)); 29 | } 30 | 31 | public boolean hasNext() { 32 | return remainingPages > 0; 33 | } 34 | 35 | public Page next() { 36 | try { 37 | XMLEvent event; 38 | String title = ""; 39 | String text = ""; 40 | while (true) { 41 | event = reader.nextEvent(); 42 | // System.out.println(event); 43 | if (event.isStartElement()) { 44 | if (event.asStartElement().getName().getLocalPart().equals("page")) { 45 | while (true) { 46 | event = reader.nextEvent(); 47 | if (event.isStartElement()) { 48 | String name = event.asStartElement().getName().getLocalPart(); 49 | if (name.equals("title")) 50 | title = reader.getElementText(); 51 | else if (name.equals("text")) 52 | text = reader.getElementText(); 53 | } else if (event.isEndElement()) { 54 | if (event.asEndElement().getName().getLocalPart().equals("page")) { 55 | --remainingPages; 56 | return new Page(title, text); 57 | } 58 | } 59 | } 60 | } 61 | } 62 | } 63 | } catch (Exception e) { 64 | throw new NoSuchElementException(); 65 | } 66 | 67 | } 68 | 69 | public void remove() { 70 | throw new UnsupportedOperationException(); 71 | } 72 | } 73 | 74 | public Iterator iterator() { 75 | try { 76 | return new PageIterator(); 77 | } catch (Exception e) { 78 | throw new RuntimeException(e); 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/2.wiki-wordcount/src/com/alg/concurrency/threading/wordcount3/concurrent/Parser.java: -------------------------------------------------------------------------------- 1 | package com.alg.concurrency.threading.wordcount3.concurrent; 2 | 3 | import java.util.Iterator; 4 | import java.util.concurrent.BlockingQueue; 5 | 6 | class Parser implements Runnable { 7 | private BlockingQueue queue; 8 | private int maxPages; 9 | private String file; 10 | 11 | public Parser(BlockingQueue queue, int maxPages, String file) { 12 | this.queue = queue; 13 | this.maxPages = maxPages; 14 | this.file = file; 15 | } 16 | 17 | public void run() { 18 | try { 19 | Iterator pages = new Pages(maxPages, file).iterator(); 20 | while(pages.hasNext()) { 21 | Page page = pages.next(); 22 | queue.put(page); 23 | //System.out.println("parser:" + page.getTitle()); 24 | } 25 | } catch (Exception e) { 26 | e.printStackTrace(); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/2.wiki-wordcount/src/com/alg/concurrency/threading/wordcount3/concurrent/Test.java: -------------------------------------------------------------------------------- 1 | package com.alg.concurrency.threading.wordcount3.concurrent; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import java.util.concurrent.ArrayBlockingQueue; 6 | import java.util.concurrent.ExecutorService; 7 | import java.util.concurrent.Executors; 8 | import java.util.concurrent.TimeUnit; 9 | 10 | public class Test { 11 | 12 | public static void main(String[] args) throws Exception { 13 | int NUM_COUNTERS = 2; 14 | ArrayBlockingQueue queue = new ArrayBlockingQueue(1000); 15 | Map counts = new HashMap(); 16 | 17 | Thread parser = new Thread(new Parser(queue, Integer.parseInt(args[0]), args[1])); 18 | ExecutorService executor = Executors.newCachedThreadPool(); 19 | for (int i = 0; i < NUM_COUNTERS; ++i) 20 | executor.execute(new WordCounter(queue, counts)); 21 | 22 | long start = System.currentTimeMillis(); 23 | parser.start(); 24 | parser.join(); 25 | for (int i = 0; i < NUM_COUNTERS; ++i) 26 | queue.put(new Page("terminate", null)); 27 | executor.shutdown(); 28 | executor.awaitTermination(10L, TimeUnit.MINUTES); 29 | long end = System.currentTimeMillis(); 30 | System.out.println("Elapsed time: " + (end - start) / 1000.0 + "s"); 31 | 32 | // for (Map.Entry e: counts.entrySet()) { 33 | // System.out.println(e); 34 | // } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/2.wiki-wordcount/src/com/alg/concurrency/threading/wordcount3/concurrent/WordCounter.java: -------------------------------------------------------------------------------- 1 | package com.alg.concurrency.threading.wordcount3.concurrent; 2 | 3 | import java.util.Map; 4 | import java.util.concurrent.BlockingQueue; 5 | import java.util.concurrent.locks.ReentrantLock; 6 | 7 | class WordCounter implements Runnable { 8 | private BlockingQueue queue; 9 | private Map counts; 10 | private ReentrantLock lock; 11 | 12 | public WordCounter(BlockingQueue queue, Map counts) { 13 | this.queue = queue; 14 | this.counts = counts; 15 | this.lock = new ReentrantLock(); 16 | } 17 | 18 | public void run() { 19 | try { 20 | while (true) { 21 | Page page = queue.take(); 22 | // System.out.println("counter:" +page.getTitle()); 23 | if (page.getTitle().equals("terminate")) 24 | break; 25 | Iterable words = new Words(page.getText()); 26 | for (String word : words) 27 | countWord(word); 28 | } 29 | } catch (Exception e) { 30 | e.printStackTrace(); 31 | } 32 | } 33 | 34 | private void countWord(String word) { 35 | lock.lock(); 36 | try { 37 | Integer currentCount = counts.get(word); 38 | if (currentCount == null) 39 | counts.put(word, 1); 40 | else 41 | counts.put(word, currentCount + 1); 42 | } finally { 43 | lock.unlock(); 44 | } 45 | 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/2.wiki-wordcount/src/com/alg/concurrency/threading/wordcount3/concurrent/Words.java: -------------------------------------------------------------------------------- 1 | package com.alg.concurrency.threading.wordcount3.concurrent; 2 | 3 | import java.text.BreakIterator; 4 | import java.util.Iterator; 5 | 6 | public class Words implements Iterable { 7 | 8 | private final String text; 9 | 10 | public Words(String text) { 11 | this.text = text; 12 | } 13 | 14 | private class WordIterator implements Iterator { 15 | 16 | private BreakIterator wordBoundary; 17 | private int start; 18 | private int end; 19 | 20 | public WordIterator() { 21 | wordBoundary = BreakIterator.getWordInstance(); 22 | wordBoundary.setText(text); 23 | start = wordBoundary.first(); 24 | end = wordBoundary.next(); 25 | } 26 | 27 | public boolean hasNext() { return end != BreakIterator.DONE; } 28 | 29 | public String next() { 30 | String s = text.substring(start, end); 31 | start = end; 32 | end = wordBoundary.next(); 33 | return s; 34 | } 35 | 36 | public void remove() { throw new UnsupportedOperationException(); } 37 | } 38 | 39 | public Iterator iterator() { 40 | return new WordIterator(); 41 | } 42 | } -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/2.wiki-wordcount/src/com/alg/concurrency/threading/wordcount4/concurrent/Page.java: -------------------------------------------------------------------------------- 1 | package com.alg.concurrency.threading.wordcount4.concurrent; 2 | 3 | class Page { 4 | private String title; 5 | private String text; 6 | 7 | public Page(String title, String text) { 8 | this.title = title; 9 | this.text = text; 10 | } 11 | 12 | public String getTitle() { 13 | return title; 14 | } 15 | 16 | public String getText() { 17 | return text; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/2.wiki-wordcount/src/com/alg/concurrency/threading/wordcount4/concurrent/Pages.java: -------------------------------------------------------------------------------- 1 | package com.alg.concurrency.threading.wordcount4.concurrent; 2 | 3 | import java.io.FileInputStream; 4 | import java.util.Iterator; 5 | import java.util.NoSuchElementException; 6 | 7 | import javax.xml.stream.XMLEventReader; 8 | import javax.xml.stream.XMLInputFactory; 9 | import javax.xml.stream.events.XMLEvent; 10 | 11 | class Pages implements Iterable { 12 | 13 | private final int maxPages; 14 | private final String fileName; 15 | 16 | public Pages(int maxPages, String fileName) { 17 | this.maxPages = maxPages; 18 | this.fileName = fileName; 19 | } 20 | 21 | private class PageIterator implements Iterator { 22 | 23 | private XMLEventReader reader; 24 | private int remainingPages; 25 | 26 | public PageIterator() throws Exception { 27 | remainingPages = maxPages; 28 | reader = XMLInputFactory.newInstance().createXMLEventReader(new FileInputStream(fileName)); 29 | } 30 | 31 | public boolean hasNext() { 32 | return remainingPages > 0; 33 | } 34 | 35 | public Page next() { 36 | try { 37 | XMLEvent event; 38 | String title = ""; 39 | String text = ""; 40 | while (true) { 41 | event = reader.nextEvent(); 42 | // System.out.println(event); 43 | if (event.isStartElement()) { 44 | if (event.asStartElement().getName().getLocalPart().equals("page")) { 45 | while (true) { 46 | event = reader.nextEvent(); 47 | if (event.isStartElement()) { 48 | String name = event.asStartElement().getName().getLocalPart(); 49 | if (name.equals("title")) 50 | title = reader.getElementText(); 51 | else if (name.equals("text")) 52 | text = reader.getElementText(); 53 | } else if (event.isEndElement()) { 54 | if (event.asEndElement().getName().getLocalPart().equals("page")) { 55 | --remainingPages; 56 | return new Page(title, text); 57 | } 58 | } 59 | } 60 | } 61 | } 62 | } 63 | } catch (Exception e) { 64 | throw new NoSuchElementException(); 65 | } 66 | 67 | } 68 | 69 | public void remove() { 70 | throw new UnsupportedOperationException(); 71 | } 72 | } 73 | 74 | public Iterator iterator() { 75 | try { 76 | return new PageIterator(); 77 | } catch (Exception e) { 78 | throw new RuntimeException(e); 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/2.wiki-wordcount/src/com/alg/concurrency/threading/wordcount4/concurrent/Parser.java: -------------------------------------------------------------------------------- 1 | package com.alg.concurrency.threading.wordcount4.concurrent; 2 | 3 | import java.util.Iterator; 4 | import java.util.concurrent.BlockingQueue; 5 | 6 | class Parser implements Runnable { 7 | private BlockingQueue queue; 8 | private int maxPages; 9 | private String file; 10 | 11 | public Parser(BlockingQueue queue, int maxPages, String file) { 12 | this.queue = queue; 13 | this.maxPages = maxPages; 14 | this.file = file; 15 | } 16 | 17 | public void run() { 18 | try { 19 | Iterator pages = new Pages(maxPages, file).iterator(); 20 | while(pages.hasNext()) { 21 | Page page = pages.next(); 22 | queue.put(page); 23 | //System.out.println("parser:" + page.getTitle()); 24 | } 25 | } catch (Exception e) { 26 | e.printStackTrace(); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/2.wiki-wordcount/src/com/alg/concurrency/threading/wordcount4/concurrent/Test.java: -------------------------------------------------------------------------------- 1 | package com.alg.concurrency.threading.wordcount4.concurrent; 2 | 3 | import java.util.concurrent.ArrayBlockingQueue; 4 | import java.util.concurrent.ConcurrentHashMap; 5 | import java.util.concurrent.ExecutorService; 6 | import java.util.concurrent.Executors; 7 | import java.util.concurrent.TimeUnit; 8 | 9 | public class Test { 10 | 11 | public static void main(String[] args) throws Exception { 12 | int NUM_COUNTERS = 4; 13 | ArrayBlockingQueue queue = new ArrayBlockingQueue(1000); 14 | ConcurrentHashMap counts = new ConcurrentHashMap(); 15 | 16 | Thread parser = new Thread(new Parser(queue, Integer.parseInt(args[0]), args[1])); 17 | ExecutorService executor = Executors.newCachedThreadPool(); 18 | for (int i = 0; i < NUM_COUNTERS; ++i) 19 | executor.execute(new WordCounter(queue, counts)); 20 | 21 | long start = System.currentTimeMillis(); 22 | parser.start(); 23 | parser.join(); 24 | for (int i = 0; i < NUM_COUNTERS; ++i) 25 | queue.put(new Page("terminate", null)); 26 | executor.shutdown(); 27 | executor.awaitTermination(10L, TimeUnit.MINUTES); 28 | long end = System.currentTimeMillis(); 29 | System.out.println("Elapsed time: " + (end - start) / 1000.0 + "s"); 30 | 31 | // for (Map.Entry e: counts.entrySet()) { 32 | // System.out.println(e); 33 | // } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/2.wiki-wordcount/src/com/alg/concurrency/threading/wordcount4/concurrent/WordCounter.java: -------------------------------------------------------------------------------- 1 | package com.alg.concurrency.threading.wordcount4.concurrent; 2 | 3 | import java.util.concurrent.BlockingQueue; 4 | import java.util.concurrent.ConcurrentMap; 5 | 6 | class WordCounter implements Runnable { 7 | private BlockingQueue queue; 8 | private ConcurrentMap counts; 9 | 10 | public WordCounter(BlockingQueue queue, ConcurrentMap counts) { 11 | this.queue = queue; 12 | this.counts = counts; 13 | } 14 | 15 | public void run() { 16 | try { 17 | while (true) { 18 | Page page = queue.take(); 19 | // System.out.println("counter:" +page.getTitle()); 20 | if (page.getTitle().equals("terminate")) 21 | break; 22 | Iterable words = new Words(page.getText()); 23 | for (String word : words) 24 | countWord(word); 25 | } 26 | } catch (Exception e) { 27 | e.printStackTrace(); 28 | } 29 | } 30 | 31 | private void countWord(String word) { 32 | while (true) { 33 | Integer currentCount = counts.get(word); 34 | if (currentCount == null) { 35 | if (counts.putIfAbsent(word, 1) == null) 36 | break; 37 | } else if (counts.replace(word, currentCount, currentCount + 1)) { 38 | break; 39 | } 40 | } 41 | 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/2.wiki-wordcount/src/com/alg/concurrency/threading/wordcount4/concurrent/Words.java: -------------------------------------------------------------------------------- 1 | package com.alg.concurrency.threading.wordcount4.concurrent; 2 | 3 | import java.text.BreakIterator; 4 | import java.util.Iterator; 5 | 6 | public class Words implements Iterable { 7 | 8 | private final String text; 9 | 10 | public Words(String text) { 11 | this.text = text; 12 | } 13 | 14 | private class WordIterator implements Iterator { 15 | 16 | private BreakIterator wordBoundary; 17 | private int start; 18 | private int end; 19 | 20 | public WordIterator() { 21 | wordBoundary = BreakIterator.getWordInstance(); 22 | wordBoundary.setText(text); 23 | start = wordBoundary.first(); 24 | end = wordBoundary.next(); 25 | } 26 | 27 | public boolean hasNext() { return end != BreakIterator.DONE; } 28 | 29 | public String next() { 30 | String s = text.substring(start, end); 31 | start = end; 32 | end = wordBoundary.next(); 33 | return s; 34 | } 35 | 36 | public void remove() { throw new UnsupportedOperationException(); } 37 | } 38 | 39 | public Iterator iterator() { 40 | return new WordIterator(); 41 | } 42 | } -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/3.webserver/src/main/java/com/alg/common/app/domain/Command.java: -------------------------------------------------------------------------------- 1 | package com.alg.common.app.domain; 2 | 3 | public abstract class Command { 4 | 5 | protected String[] command; 6 | protected WDIService wdiService; 7 | 8 | public Command(String[] command, WDIService wdiService) { 9 | this.command = command; 10 | this.wdiService = wdiService; 11 | } 12 | 13 | public abstract String execute(); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/3.webserver/src/main/java/com/alg/common/app/domain/Constants.java: -------------------------------------------------------------------------------- 1 | package com.alg.common.app.domain; 2 | 3 | /** 4 | * Necessary constants for the behaviour of the server 5 | * @author author 6 | * 7 | */ 8 | public class Constants { 9 | 10 | /** 11 | * Port where the serial server will be hearing 12 | */ 13 | public static final int SERIAL_PORT=2220; 14 | 15 | /** 16 | * Port where the concurrent version will be hearing 17 | */ 18 | public static final int CONCURRENT_PORT = 2221; 19 | 20 | /** 21 | * Path to the file with the WDI data 22 | */ 23 | public static final String DATA_ROUTE="G:/WDIData.csv"; 24 | 25 | public static final int NUM_FEATURES = 65; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/3.webserver/src/main/java/com/alg/common/app/domain/ErrorCommand.java: -------------------------------------------------------------------------------- 1 | package com.alg.common.app.domain; 2 | 3 | public class ErrorCommand extends Command { 4 | 5 | public ErrorCommand(String[] command, WDIService wdiService) { 6 | super(command, wdiService); 7 | } 8 | 9 | public String execute() { 10 | return "Unknown command: " + command[0]; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/3.webserver/src/main/java/com/alg/common/app/domain/QueryCommand.java: -------------------------------------------------------------------------------- 1 | package com.alg.common.app.domain; 2 | 3 | public class QueryCommand extends Command { 4 | 5 | public QueryCommand(String[] command, WDIService wdiService) { 6 | super(command, wdiService); 7 | } 8 | 9 | public String execute() { 10 | 11 | if (command.length == 3) { 12 | return wdiService.query(command[1], command[2]); 13 | } else { 14 | return "ERROR;Bad Command"; 15 | } 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/3.webserver/src/main/java/com/alg/common/app/domain/ReportCommand.java: -------------------------------------------------------------------------------- 1 | package com.alg.common.app.domain; 2 | 3 | public class ReportCommand extends Command { 4 | 5 | public ReportCommand(String[] command, WDIService wdiService) { 6 | super(command, wdiService); 7 | } 8 | 9 | public String execute() { 10 | return wdiService.report(command[1]); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/3.webserver/src/main/java/com/alg/common/app/domain/StopCommand.java: -------------------------------------------------------------------------------- 1 | package com.alg.common.app.domain; 2 | 3 | public class StopCommand extends Command { 4 | 5 | public StopCommand(String[] command, WDIService wdiService) { 6 | super(command, wdiService); 7 | } 8 | 9 | public String execute() { 10 | return "Server stopped"; 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/3.webserver/src/main/java/com/alg/common/app/domain/WDI.java: -------------------------------------------------------------------------------- 1 | package com.alg.common.app.domain; 2 | 3 | import javax.persistence.Column; 4 | import javax.persistence.Entity; 5 | import javax.persistence.GeneratedValue; 6 | import javax.persistence.GenerationType; 7 | import javax.persistence.Id; 8 | 9 | @Entity 10 | public class WDI { 11 | @Id 12 | @GeneratedValue(strategy = GenerationType.AUTO) 13 | private Long id; 14 | private String countryName; 15 | private String countryCode; 16 | private String indicatorName; 17 | private String indicatorCode; 18 | @Column(length = 1000) 19 | private String year_values; 20 | 21 | public void setData(String[] data) throws Exception { 22 | if (data.length != Constants.NUM_FEATURES) { 23 | throw new Exception("Data length is not correct: " + data.length); 24 | } 25 | countryName = getString(data[0]); 26 | countryCode = getString(data[1]); 27 | indicatorName = getString(data[2]); 28 | indicatorCode = getString(data[3]); 29 | String res = ""; 30 | for (int i = 4; i < data.length; ++i) { 31 | if (data[i].trim().length() == 0) 32 | res += "0.0,"; 33 | else 34 | res += data[i] + ","; 35 | } 36 | year_values = res; 37 | 38 | } 39 | 40 | private String getString(String string) { 41 | if (string.startsWith("\"")) { 42 | return string.substring(1, string.length() - 1); 43 | } 44 | return string; 45 | } 46 | 47 | public Long getId() { 48 | return id; 49 | } 50 | 51 | public void setId(Long id) { 52 | this.id = id; 53 | } 54 | 55 | public String getCountryName() { 56 | return countryName; 57 | } 58 | 59 | public void setCountryName(String countryName) { 60 | this.countryName = countryName; 61 | } 62 | 63 | public String getCountryCode() { 64 | return countryCode; 65 | } 66 | 67 | public void setCountryCode(String countryCode) { 68 | this.countryCode = countryCode; 69 | } 70 | 71 | public String getIndicatorName() { 72 | return indicatorName; 73 | } 74 | 75 | public void setIndicatorName(String indicatorName) { 76 | this.indicatorName = indicatorName; 77 | } 78 | 79 | public String getIndicatorCode() { 80 | return indicatorCode; 81 | } 82 | 83 | public void setIndicatorCode(String indicatorCode) { 84 | this.indicatorCode = indicatorCode; 85 | } 86 | 87 | public String getYear_values() { 88 | return year_values; 89 | } 90 | 91 | public void setYear_values(String year_values) { 92 | this.year_values = year_values; 93 | } 94 | 95 | @Override 96 | public String toString() { 97 | return "WDI [id=" + id + ", countryName=" + countryName + ", countryCode=" + countryCode + ", indicatorName=" 98 | + indicatorName + ", indicatorCode=" + indicatorCode + ", year_values=" + year_values + "]"; 99 | } 100 | 101 | 102 | 103 | } 104 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/3.webserver/src/main/java/com/alg/common/app/domain/WDILoader.java: -------------------------------------------------------------------------------- 1 | package com.alg.common.app.domain; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.io.InputStreamReader; 7 | import java.nio.file.Files; 8 | import java.nio.file.Path; 9 | import java.nio.file.Paths; 10 | import java.util.ArrayList; 11 | import java.util.List; 12 | 13 | public class WDILoader { 14 | 15 | public static List load() { 16 | Path file = Paths.get(Constants.DATA_ROUTE); 17 | List dataSet = new ArrayList<>(); 18 | int lineNumber = 1; 19 | try (InputStream in = Files.newInputStream(file); 20 | BufferedReader reader = new BufferedReader(new InputStreamReader(in))) { 21 | String line = null; 22 | // First line are headers 23 | line = reader.readLine(); 24 | while ((line = reader.readLine()) != null) { 25 | String data[] = parse(line); 26 | ++lineNumber; 27 | WDI dataObject = new WDI(); 28 | dataObject.setData(data); 29 | dataSet.add(dataObject); 30 | if (lineNumber == 10) { 31 | System.out.println("data loading finished"); 32 | break; 33 | } 34 | } 35 | } catch (IOException x) { 36 | x.printStackTrace(); 37 | } catch (Exception e) { 38 | e.printStackTrace(); 39 | } 40 | return dataSet; 41 | } 42 | 43 | private static String[] parse(String line) { 44 | String[] ret = new String[65]; 45 | int index = 0; 46 | StringBuffer buffer = new StringBuffer(); 47 | boolean enComillas = false; 48 | for (int i = 0; i < line.length(); i++) { 49 | char letra = line.charAt(i); 50 | if (letra == '"') { 51 | enComillas = !enComillas; 52 | } else if ((letra == ',') && (enComillas == false)) { 53 | ret[index] = buffer.toString(); 54 | index++; 55 | buffer = new StringBuffer(); 56 | } else { 57 | buffer.append(letra); 58 | } 59 | } 60 | ret[index] = buffer.toString(); 61 | index++; 62 | return ret; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/3.webserver/src/main/java/com/alg/common/app/domain/WDIService.java: -------------------------------------------------------------------------------- 1 | package com.alg.common.app.domain; 2 | 3 | import java.io.StringWriter; 4 | import java.util.List; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | import com.alg.common.app.repository.IWDIRepository; 10 | 11 | @Service 12 | public class WDIService { 13 | 14 | @Autowired 15 | private IWDIRepository repository; 16 | 17 | public void load() { 18 | List dataSet = WDILoader.load(); 19 | for (WDI wdi : dataSet) 20 | repository.save(wdi); 21 | 22 | } 23 | 24 | public String query(String countryCode, String indicatorCode) { 25 | List res = repository.findByCountryCodeAndIndicatorCode(countryCode, indicatorCode); 26 | // System.out.println("Service query:" + res); 27 | if (res.size() != 1) 28 | return null; 29 | 30 | StringWriter writer = new StringWriter(); 31 | writer.write(countryCode); 32 | writer.write(";"); 33 | writer.write(indicatorCode); 34 | writer.write(";"); 35 | String tmp = res.get(0).getYear_values(); 36 | String[] year_values = tmp.split(","); 37 | for (int i = 0; i < year_values.length; i++) { 38 | writer.write(year_values[i].toString()); 39 | if (i < year_values.length - 1) { 40 | writer.write(";"); 41 | } 42 | } 43 | return writer.toString(); 44 | } 45 | 46 | public String report(String indicatorCode) { 47 | List data = repository.findByIndicatorCode(indicatorCode); 48 | // System.out.println("Service report:" + data); 49 | 50 | StringWriter writer = new StringWriter(); 51 | writer.write(indicatorCode); 52 | writer.write(";"); 53 | for (int i = 0; i < data.size(); i++) { 54 | WDI wdi = data.get(i); 55 | String[] year_values = wdi.getYear_values().split(","); 56 | 57 | double mean = 0.0; 58 | for (int j = 0; j < year_values.length; j++) 59 | mean += Double.valueOf(year_values[j]); 60 | mean /= year_values.length; 61 | writer.write(wdi.getCountryCode()); 62 | writer.write(";"); 63 | writer.write("" + mean); 64 | writer.write(";"); 65 | } 66 | return writer.toString(); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/3.webserver/src/main/java/com/alg/common/app/repository/IWDIRepository.java: -------------------------------------------------------------------------------- 1 | package com.alg.common.app.repository; 2 | 3 | import java.util.List; 4 | 5 | import org.springframework.data.jpa.repository.JpaRepository; 6 | 7 | import com.alg.common.app.domain.WDI; 8 | 9 | public interface IWDIRepository extends JpaRepository { 10 | 11 | List findByCountryCodeAndIndicatorCode(String countryCode, String indicatorCode); 12 | 13 | List findByIndicatorCode(String indicatorCode); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/3.webserver/src/main/java/com/alg/webserver/benchmark/MyBenchmark.java: -------------------------------------------------------------------------------- 1 | package com.alg.webserver.benchmark; 2 | 3 | import java.io.PrintWriter; 4 | import java.io.StringWriter; 5 | import java.net.Socket; 6 | import java.util.List; 7 | import java.util.Scanner; 8 | import java.util.concurrent.TimeUnit; 9 | 10 | import org.openjdk.jmh.annotations.Benchmark; 11 | import org.openjdk.jmh.annotations.BenchmarkMode; 12 | import org.openjdk.jmh.annotations.Fork; 13 | import org.openjdk.jmh.annotations.Level; 14 | import org.openjdk.jmh.annotations.Measurement; 15 | import org.openjdk.jmh.annotations.Mode; 16 | import org.openjdk.jmh.annotations.OutputTimeUnit; 17 | import org.openjdk.jmh.annotations.Param; 18 | import org.openjdk.jmh.annotations.Scope; 19 | import org.openjdk.jmh.annotations.State; 20 | import org.openjdk.jmh.annotations.TearDown; 21 | import org.openjdk.jmh.annotations.Warmup; 22 | 23 | import com.alg.common.app.domain.Constants; 24 | import com.alg.common.app.domain.WDI; 25 | import com.alg.common.app.domain.WDILoader; 26 | import com.alg.webserver.client.SerialClient; 27 | 28 | @State(Scope.Benchmark) 29 | public class MyBenchmark { 30 | 31 | @Param({ "2" }) 32 | private int numClients; 33 | 34 | private List data = WDILoader.load(); 35 | 36 | @Benchmark 37 | @BenchmarkMode(Mode.SingleShotTime) 38 | @Fork(1) 39 | @Warmup(iterations = 10, time = 1, batchSize = 1) 40 | @Measurement(iterations = 10, time = 1, batchSize = 1) 41 | @OutputTimeUnit(TimeUnit.MILLISECONDS) 42 | public void serialClients() { 43 | System.out.println("Serial: Number of Simultaneous Clients: " + numClients); 44 | Thread[] threads = new Thread[numClients]; 45 | for (int j = 0; j < numClients; j++) { 46 | SerialClient client = new SerialClient(data); 47 | threads[j] = new Thread(client); 48 | threads[j].start(); 49 | } 50 | 51 | for (int j = 0; j < numClients; j++) { 52 | try { 53 | threads[j].join(); 54 | } catch (InterruptedException e) { 55 | e.printStackTrace(); 56 | } 57 | } 58 | } 59 | 60 | @TearDown(Level.Trial) 61 | public void shutdownSerial() { 62 | System.out.println("Shutting down serial server"); 63 | try { 64 | Socket socket = new Socket("localhost", Constants.SERIAL_PORT); 65 | PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 66 | Scanner in = new Scanner(socket.getInputStream()); 67 | 68 | StringWriter writer = new StringWriter(); 69 | writer.write("z"); 70 | writer.write(";"); 71 | 72 | String command = writer.toString(); 73 | out.println(command); 74 | String output = in.nextLine(); 75 | 76 | } catch (Exception e) { 77 | e.printStackTrace(); 78 | } 79 | } 80 | 81 | public static void main(String[] args) throws Exception { 82 | org.openjdk.jmh.Main.main(args); 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/3.webserver/src/main/java/com/alg/webserver/client/ConcurrentClients.java: -------------------------------------------------------------------------------- 1 | package com.alg.webserver.client; 2 | 3 | import java.io.PrintWriter; 4 | import java.io.StringWriter; 5 | import java.net.Socket; 6 | import java.util.List; 7 | import java.util.Scanner; 8 | 9 | import com.alg.common.app.domain.Constants; 10 | import com.alg.common.app.domain.WDI; 11 | import com.alg.common.app.domain.WDILoader; 12 | 13 | public class ConcurrentClients { 14 | 15 | public static void main(String[] args) { 16 | final int numClients = 2; 17 | List data = WDILoader.load(); 18 | System.out.println("Number of Simultaneous Clients: " + numClients); 19 | Thread[] threads = new Thread[numClients]; 20 | for (int j = 0; j < numClients; j++) { 21 | SerialClient client = new SerialClient(data); 22 | threads[j] = new Thread(client); 23 | threads[j].start(); 24 | } 25 | 26 | for (int j = 0; j < numClients; j++) { 27 | try { 28 | threads[j].join(); 29 | } catch (InterruptedException e) { 30 | e.printStackTrace(); 31 | } 32 | } 33 | 34 | /* 35 | * try { Socket socket = new Socket("localhost", Constants.SERIAL_PORT); 36 | * PrintWriter out = new PrintWriter(socket.getOutputStream(), true); Scanner in 37 | * = new Scanner(socket.getInputStream()); 38 | * 39 | * StringWriter writer = new StringWriter(); writer.write("z"); 40 | * writer.write(";"); 41 | * 42 | * String command = writer.toString(); out.println(command); String output = 43 | * in.nextLine(); 44 | * 45 | * } catch (Exception e) { e.printStackTrace(); } 46 | */ 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/3.webserver/src/main/java/com/alg/webserver/client/SerialClient.java: -------------------------------------------------------------------------------- 1 | package com.alg.webserver.client; 2 | 3 | import java.io.PrintWriter; 4 | import java.io.StringWriter; 5 | import java.net.Socket; 6 | import java.util.List; 7 | import java.util.Random; 8 | import java.util.Scanner; 9 | 10 | import com.alg.common.app.domain.Constants; 11 | import com.alg.common.app.domain.WDI; 12 | 13 | public class SerialClient implements Runnable { 14 | private Socket socket; 15 | private PrintWriter out; 16 | private Scanner in; 17 | private List data; 18 | 19 | public SerialClient(List data) { 20 | this.data = data; 21 | } 22 | 23 | private void startConnection() throws Exception { 24 | socket = new Socket("localhost", Constants.SERIAL_PORT); 25 | out = new PrintWriter(socket.getOutputStream(), true); 26 | in = new Scanner(socket.getInputStream()); 27 | } 28 | 29 | private void closeConnection() throws Exception { 30 | in.close(); 31 | out.close(); 32 | socket.close(); 33 | } 34 | 35 | public void run() { 36 | Random randomGenerator = new Random(); 37 | 38 | try { 39 | for (int i = 0; i < 10; i++) { 40 | for (int j = 0; j < 9; j++) { 41 | startConnection(); 42 | WDI wdi = data.get(randomGenerator.nextInt(data.size())); 43 | 44 | StringWriter writer = new StringWriter(); 45 | writer.write("q"); 46 | writer.write(";"); 47 | writer.write(wdi.getCountryCode()); 48 | writer.write(";"); 49 | writer.write(wdi.getIndicatorCode()); 50 | System.out.println("Query INPUT: " + writer); 51 | out.println(writer.toString()); 52 | String output = in.nextLine(); 53 | System.out.println("Query OUTPUT: " + output); 54 | closeConnection(); 55 | 56 | startConnection(); 57 | writer = new StringWriter(); 58 | writer.write("r"); 59 | writer.write(";"); 60 | writer.write(wdi.getIndicatorCode()); 61 | System.out.println("Report INPUT: " + writer); 62 | out.println(writer.toString()); 63 | output = in.nextLine(); 64 | System.out.println("Report OUTPUT: " + output); 65 | closeConnection(); 66 | 67 | } 68 | 69 | } 70 | } catch (Exception e) { 71 | System.out.println(e); 72 | } 73 | 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/3.webserver/src/main/java/com/alg/webserver/concurrent/threadperconnection/EventHandler.java: -------------------------------------------------------------------------------- 1 | package com.alg.webserver.concurrent.threadperconnection; 2 | 3 | import java.io.PrintWriter; 4 | import java.net.Socket; 5 | import java.util.Scanner; 6 | 7 | import com.alg.common.app.domain.Command; 8 | import com.alg.common.app.domain.ErrorCommand; 9 | import com.alg.common.app.domain.QueryCommand; 10 | import com.alg.common.app.domain.ReportCommand; 11 | import com.alg.common.app.domain.WDIService; 12 | 13 | public class EventHandler extends Thread { 14 | private Socket socket; 15 | private WDIService wdiService; 16 | 17 | public EventHandler(Socket socket, WDIService wdiService) { 18 | this.socket = socket; 19 | this.wdiService = wdiService; 20 | } 21 | 22 | @Override 23 | public void run() { 24 | try { 25 | Scanner in = new Scanner(socket.getInputStream()); 26 | PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 27 | Command command; 28 | 29 | String line = in.nextLine(); 30 | String[] commandData = line.split(";"); 31 | System.out.println("Command: " + commandData[0]); 32 | switch (commandData[0]) { 33 | case "q": 34 | System.out.println("Query"); 35 | command = new QueryCommand(commandData, wdiService); 36 | break; 37 | case "r": 38 | System.out.println("Report"); 39 | command = new ReportCommand(commandData, wdiService); 40 | break; 41 | default: 42 | System.out.println("Error"); 43 | command = new ErrorCommand(commandData, wdiService); 44 | } 45 | String response = command.execute(); 46 | System.out.println(response); 47 | out.println(response); 48 | in.close(); 49 | out.close(); 50 | socket.close(); 51 | } catch (Exception e) { 52 | 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/3.webserver/src/main/java/com/alg/webserver/concurrent/threadperconnection/WebServer.java: -------------------------------------------------------------------------------- 1 | package com.alg.webserver.concurrent.threadperconnection; 2 | 3 | import java.net.ServerSocket; 4 | import java.net.Socket; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.CommandLineRunner; 8 | import org.springframework.boot.SpringApplication; 9 | import org.springframework.boot.autoconfigure.SpringBootApplication; 10 | import org.springframework.boot.autoconfigure.domain.EntityScan; 11 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 12 | 13 | import com.alg.common.app.domain.Constants; 14 | import com.alg.common.app.domain.WDIService; 15 | 16 | @SpringBootApplication(scanBasePackages = { "com.alg.common.app.domain", "com.alg.common.app.repository" }) 17 | @EnableJpaRepositories("com.alg.common.app.repository") 18 | @EntityScan("com.alg.common.app.domain") 19 | public class WebServer implements CommandLineRunner { 20 | @Autowired 21 | WDIService wdiService; 22 | 23 | public static void main(String[] args) throws Exception { 24 | SpringApplication.run(WebServer.class, args); 25 | } 26 | 27 | @Override 28 | public void run(String... strings) throws Exception { 29 | wdiService.load(); 30 | ServerSocket server = new ServerSocket(Constants.SERIAL_PORT); 31 | while (true) { 32 | Socket socket = server.accept(); 33 | Thread handler = new EventHandler(socket, wdiService); 34 | handler.start(); 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/3.webserver/src/main/java/com/alg/webserver/concurrent/threadpool/EventHandler.java: -------------------------------------------------------------------------------- 1 | package com.alg.webserver.concurrent.threadpool; 2 | 3 | import java.io.PrintWriter; 4 | import java.net.Socket; 5 | import java.util.Scanner; 6 | 7 | import com.alg.common.app.domain.Command; 8 | import com.alg.common.app.domain.ErrorCommand; 9 | import com.alg.common.app.domain.QueryCommand; 10 | import com.alg.common.app.domain.ReportCommand; 11 | import com.alg.common.app.domain.WDIService; 12 | 13 | public class EventHandler extends Thread { 14 | private Socket socket; 15 | private WDIService wdiService; 16 | 17 | public EventHandler(Socket socket, WDIService wdiService) { 18 | this.socket = socket; 19 | this.wdiService = wdiService; 20 | } 21 | 22 | @Override 23 | public void run() { 24 | try { 25 | Scanner in = new Scanner(socket.getInputStream()); 26 | PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 27 | Command command; 28 | 29 | String line = in.nextLine(); 30 | String[] commandData = line.split(";"); 31 | System.out.println("Command: " + commandData[0]); 32 | switch (commandData[0]) { 33 | case "q": 34 | System.out.println("Query"); 35 | command = new QueryCommand(commandData, wdiService); 36 | break; 37 | case "r": 38 | System.out.println("Report"); 39 | command = new ReportCommand(commandData, wdiService); 40 | break; 41 | default: 42 | System.out.println("Error"); 43 | command = new ErrorCommand(commandData, wdiService); 44 | } 45 | String response = command.execute(); 46 | System.out.println(response); 47 | out.println(response); 48 | in.close(); 49 | out.close(); 50 | socket.close(); 51 | } catch (Exception e) { 52 | 53 | } 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/3.webserver/src/main/java/com/alg/webserver/concurrent/threadpool/WebServer.java: -------------------------------------------------------------------------------- 1 | package com.alg.webserver.concurrent.threadpool; 2 | 3 | import java.net.ServerSocket; 4 | import java.net.Socket; 5 | import java.util.concurrent.ExecutorService; 6 | import java.util.concurrent.Executors; 7 | 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.CommandLineRunner; 10 | import org.springframework.boot.SpringApplication; 11 | import org.springframework.boot.autoconfigure.SpringBootApplication; 12 | import org.springframework.boot.autoconfigure.domain.EntityScan; 13 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 14 | 15 | import com.alg.common.app.domain.Constants; 16 | import com.alg.common.app.domain.WDIService; 17 | 18 | @SpringBootApplication(scanBasePackages = { "com.alg.common.app.domain", "com.alg.common.app.repository" }) 19 | @EnableJpaRepositories("com.alg.common.app.repository") 20 | @EntityScan("com.alg.common.app.domain") 21 | public class WebServer implements CommandLineRunner { 22 | @Autowired 23 | WDIService wdiService; 24 | 25 | public static void main(String[] args) throws Exception { 26 | SpringApplication.run(WebServer.class, args); 27 | } 28 | 29 | @Override 30 | public void run(String... strings) throws Exception { 31 | wdiService.load(); 32 | ServerSocket server = new ServerSocket(Constants.SERIAL_PORT); 33 | int threadPoolSize = Runtime.getRuntime().availableProcessors() * 2; 34 | ExecutorService executor = Executors.newFixedThreadPool(threadPoolSize); 35 | while (true) { 36 | Socket socket = server.accept(); 37 | executor.execute(new EventHandler(socket, wdiService)); 38 | } 39 | //executor.shutdown(); 40 | //executor.awaitTermination(1, TimeUnit.DAYS); 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/3.webserver/src/main/java/com/alg/webserver/serial/EventHandler.java: -------------------------------------------------------------------------------- 1 | package com.alg.webserver.serial; 2 | 3 | import java.io.PrintWriter; 4 | import java.net.Socket; 5 | import java.util.Scanner; 6 | 7 | import com.alg.common.app.domain.Command; 8 | import com.alg.common.app.domain.ErrorCommand; 9 | import com.alg.common.app.domain.QueryCommand; 10 | import com.alg.common.app.domain.ReportCommand; 11 | import com.alg.common.app.domain.WDIService; 12 | 13 | public class EventHandler { 14 | 15 | public static void handle(Socket socket, WDIService wdiService) { 16 | 17 | try { 18 | Scanner in = new Scanner(socket.getInputStream()); 19 | PrintWriter out = new PrintWriter(socket.getOutputStream(), true); 20 | Command command; 21 | 22 | String line = in.nextLine(); 23 | String[] commandData = line.split(";"); 24 | System.out.println("Command: " + commandData[0]); 25 | switch (commandData[0]) { 26 | case "q": 27 | System.out.println("Query"); 28 | command = new QueryCommand(commandData, wdiService); 29 | break; 30 | case "r": 31 | System.out.println("Report"); 32 | command = new ReportCommand(commandData, wdiService); 33 | break; 34 | default: 35 | System.out.println("Error"); 36 | command = new ErrorCommand(commandData, wdiService); 37 | } 38 | String response = command.execute(); 39 | System.out.println(response); 40 | out.println(response); 41 | in.close(); 42 | out.close(); 43 | socket.close(); 44 | } catch (Exception e) { 45 | 46 | } 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/3.webserver/src/main/java/com/alg/webserver/serial/WebServer.java: -------------------------------------------------------------------------------- 1 | package com.alg.webserver.serial; 2 | 3 | import java.net.ServerSocket; 4 | import java.net.Socket; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.CommandLineRunner; 8 | import org.springframework.boot.SpringApplication; 9 | import org.springframework.boot.autoconfigure.SpringBootApplication; 10 | import org.springframework.boot.autoconfigure.domain.EntityScan; 11 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 12 | 13 | import com.alg.common.app.domain.Constants; 14 | import com.alg.common.app.domain.WDIService; 15 | 16 | @SpringBootApplication(scanBasePackages = { "com.alg.common.app.domain", "com.alg.common.app.repository" }) 17 | @EnableJpaRepositories("com.alg.common.app.repository") 18 | @EntityScan("com.alg.common.app.domain") 19 | public class WebServer implements CommandLineRunner { 20 | @Autowired 21 | WDIService wdiService; 22 | 23 | public static void main(String[] args) throws Exception { 24 | SpringApplication.run(WebServer.class, args); 25 | } 26 | 27 | @Override 28 | public void run(String... strings) throws Exception { 29 | wdiService.load(); 30 | ServerSocket server = new ServerSocket(Constants.SERIAL_PORT); 31 | while (true) { 32 | Socket socket = server.accept(); 33 | EventHandler.handle(socket, wdiService); 34 | } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /2019-aug/concurrency and parallel patterns/3.webserver/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.main.web-application-type=NONE -------------------------------------------------------------------------------- /2019-aug/db-script.sql: -------------------------------------------------------------------------------- 1 | drop database if exists test; 2 | create database test; 3 | use test; 4 | CREATE TABLE `products` ( 5 | `product_id` varchar(45) NOT NULL, 6 | `product_name` varchar(45) DEFAULT NULL, 7 | `price` float DEFAULT NULL, 8 | PRIMARY KEY (`product_id`) 9 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 10 | 11 | INSERT INTO `test`.`products` 12 | (`product_id`, 13 | `product_name`, 14 | `price`) 15 | VALUES 16 | ('100', 'product1', 100); 17 | 18 | INSERT INTO `test`.`products` 19 | (`product_id`, 20 | `product_name`, 21 | `price`) 22 | VALUES 23 | ('101', 'product2', 200); 24 | 25 | INSERT INTO `test`.`products` 26 | (`product_id`, 27 | `product_name`, 28 | `price`) 29 | VALUES 30 | ('102', 'product3', 300); 31 | 32 | CREATE TABLE `ingredients` ( 33 | `ingredient_id` varchar(45) NOT NULL, 34 | `ingredient_name` varchar(45) DEFAULT NULL, 35 | `price` float DEFAULT NULL, 36 | `color` varchar(45) DEFAULT NULL, 37 | PRIMARY KEY (`ingredient_id`) 38 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=' '; 39 | 40 | INSERT INTO `test`.`ingredients` 41 | (`ingredient_id`, 42 | `ingredient_name`, 43 | `price`, 44 | `color`) 45 | VALUES 46 | ('10', 'INGR1', 10, 'RED'); 47 | 48 | INSERT INTO `test`.`ingredients` 49 | (`ingredient_id`, 50 | `ingredient_name`, 51 | `price`, 52 | `color`) 53 | VALUES 54 | ('11', 'INGR2', 20, 'GREEN'); 55 | 56 | INSERT INTO `test`.`ingredients` 57 | (`ingredient_id`, 58 | `ingredient_name`, 59 | `price`, 60 | `color`) 61 | VALUES 62 | ('12', 'INGR3', 30, 'BLUE'); 63 | 64 | CREATE TABLE `orders` ( 65 | `order_id` varchar(45) NOT NULL, 66 | `price` float DEFAULT NULL, 67 | `product_id` varchar(45), 68 | `ingredient_id` varchar(45), 69 | `email` varchar(45), 70 | `tel` varchar(45), 71 | PRIMARY KEY (`order_id`) 72 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 73 | 74 | -------------------------------------------------------------------------------- /event-driven-arch-pattern/com/alg/ap/eventdriven2/EventBus.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.eventdriven2; 2 | 3 | import java.util.List; 4 | 5 | public class EventBus { 6 | private ListenersRegistry listenersRegistry; 7 | private String tag = ""; 8 | 9 | public EventBus(String tag) { 10 | listenersRegistry = new ListenersRegistry(); 11 | this.tag = tag; 12 | } 13 | 14 | /** 15 | * Registers an event listener to the event bus 16 | */ 17 | public void register(Object listener) { 18 | if (listener == null) { 19 | System.out.println("Null object can not be registered."); 20 | } else { 21 | System.out.println("Registering listener " + listener); 22 | listenersRegistry.register(listener); 23 | } 24 | } 25 | 26 | /** 27 | * De-registers a listener object that has been registered with the event bus. 28 | * After de-registration, the object cease to listen to any further event. 29 | * */ 30 | public void deregister(Object listener) { 31 | if (listener == null) { 32 | System.out.println("Null object can not be de-registered."); 33 | } else { 34 | System.out.println("Un-Registering listener " + listener); 35 | listenersRegistry.deregister(listener); 36 | } 37 | } 38 | 39 | /** 40 | * Posts an event to the event bus. 41 | * */ 42 | public void post(Object event) throws Exception { 43 | if (event == null) { 44 | System.out.println("Null event can not be posted."); 45 | return; 46 | } 47 | System.out.println("Event " + event + " has been posted to the bus " + tag); 48 | 49 | List subscribers = listenersRegistry.getSubscribers(event); 50 | if (subscribers != null && !subscribers.isEmpty()) { 51 | System.out.println("Total subscribers found for event " + event + " is = " + subscribers.size()); 52 | System.out.println("Dispatching event " + event); 53 | for(ListenerMethod listenerMethod: subscribers) { 54 | listenerMethod.method.invoke(listenerMethod.target, event); 55 | } 56 | } 57 | } 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /event-driven-arch-pattern/com/alg/ap/eventdriven2/ListenerMethod.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.eventdriven2; 2 | 3 | import java.lang.reflect.Method; 4 | import java.lang.reflect.Modifier; 5 | 6 | 7 | public class ListenerMethod { 8 | Object target; 9 | Method method; 10 | Class eventType; 11 | 12 | 13 | ListenerMethod(Method method, Class eventType) { 14 | this.method = method; 15 | this.eventType = eventType; 16 | } 17 | 18 | /* @Override 19 | public boolean equals(Object obj) { 20 | if (this == obj) 21 | return true; 22 | if (obj == null) 23 | return false; 24 | if (getClass() != obj.getClass()) 25 | return false; 26 | ListenerMethod other = (ListenerMethod) obj; 27 | 28 | return other.method.getName().equals(method.getName()) 29 | && other.method.getModifiers() != Modifier.PRIVATE 30 | && method.getModifiers() != Modifier.PRIVATE 31 | && eventType.equals(other.eventType) 32 | && target != null 33 | && other.target != null 34 | && target.equals(other.target); 35 | } 36 | 37 | @Override 38 | public int hashCode() { 39 | return new HashCodeBuilder() 40 | .append(method) 41 | .append(target) 42 | .append(eventType) 43 | .toHashCode(); 44 | return 10; 45 | }*/ 46 | 47 | @Override 48 | public String toString() { 49 | return "[" + 50 | "method = " + 51 | method.getName() + 52 | ", target = " + 53 | target + 54 | ", event = " + 55 | eventType.getName() + 56 | "]"; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /event-driven-arch-pattern/com/alg/ap/eventdriven2/ListenersRegistry.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.eventdriven2; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | import java.util.concurrent.ConcurrentHashMap; 6 | import java.util.concurrent.CopyOnWriteArrayList; 7 | 8 | public class ListenersRegistry { 9 | // keep track of event and its registered subscribed methods 10 | private Map, List> registry = 11 | new ConcurrentHashMap, List>(); 12 | // cache to keep track of all listener object 13 | private List subscriberCache = new CopyOnWriteArrayList(); 14 | 15 | 16 | void register(Object listener) { 17 | if (subscriberCache.contains(listener)) { 18 | System.out.println(listener + " has already been registered."); 19 | } 20 | subscriberCache.add(listener); 21 | 22 | // extract all subscribed methods from the listener and its super class and interfaces. 23 | List subscribedMethods = ReflectionUtil.findSubscribedMethods(listener.getClass()); 24 | if (subscribedMethods == null || subscribedMethods.isEmpty()) { 25 | System.out.println(listener + " does not have any method marked with @Subscribe."); 26 | } 27 | 28 | for (ListenerMethod listenerMethod : subscribedMethods) { 29 | listenerMethod.target = listener; 30 | Class eventType = listenerMethod.eventType; 31 | if (registry.containsKey(eventType)) { 32 | List listenerMethods = registry.get(eventType); 33 | 34 | // check ListenerMethod's equals method 35 | if (!listenerMethods.contains(listenerMethod)) { 36 | listenerMethods.add(listenerMethod); 37 | System.out.println(listenerMethod + " has been registered."); 38 | } else { 39 | System.out.println(listenerMethod + " has already been registered."); 40 | } 41 | } else { 42 | List listenerMethods = new CopyOnWriteArrayList(); 43 | listenerMethods.add(listenerMethod); 44 | registry.put(listenerMethod.eventType, listenerMethods); 45 | System.out.println(listenerMethod + " has been registered."); 46 | } 47 | } 48 | } 49 | 50 | /** 51 | * De-registers a listener object. 52 | * */ 53 | void deregister(Object listener) { 54 | for (Object object : subscriberCache) { 55 | if (object.equals(listener)) { 56 | // found in strong cache, remove it break 57 | if (subscriberCache.remove(listener)) { 58 | System.out.println(listener + " removed from the subscriber cache."); 59 | } 60 | break; 61 | } 62 | } 63 | 64 | // iterate the whole registry map 65 | for (Map.Entry, List> entry : registry.entrySet()) { 66 | List subscribedMethods = entry.getValue(); 67 | for (ListenerMethod listenerMethod : subscribedMethods) { 68 | if (listenerMethod.target.equals(listener)) { 69 | if (subscribedMethods.remove(listenerMethod)) { 70 | System.out.println(listenerMethod + " has been un-registered."); 71 | } 72 | } 73 | } 74 | } 75 | 76 | } 77 | 78 | /** 79 | * Get all registered subscriber information for an event. 80 | * */ 81 | List getSubscribers(Object event) { 82 | if (event != null) { 83 | Class eventType = event.getClass(); 84 | // loop through the registry to get all subscribed method 85 | if (registry.containsKey(eventType)) { 86 | return registry.get(eventType); 87 | } 88 | } 89 | return null; 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /event-driven-arch-pattern/com/alg/ap/eventdriven2/ReflectionUtil.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.eventdriven2; 2 | 3 | 4 | import java.lang.reflect.Method; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * A reflection utility class to extract information about subscriber methods 10 | * from a registering listener object. 11 | */ 12 | class ReflectionUtil { 13 | /** 14 | * Finds all subscriber methods in the whole class hierarchy of {@code subscribedClass}. 15 | * 16 | * */ 17 | static List findSubscribedMethods(Class subscribedClass) { 18 | List listenerMethodList = new ArrayList(); 19 | if (subscribedClass != null) { 20 | Method[] declaredMethods = subscribedClass.getDeclaredMethods(); 21 | for (Method method : declaredMethods) { 22 | if (method.isAnnotationPresent(Subscribe.class) && !method.isBridge() && !method.isSynthetic()) { 23 | if (method.getParameterTypes().length != 1) { 24 | System.out.println(method.getName() + " has @Subscribe annotation, " + 25 | "but it should have exactly 1 parameter."); 26 | } 27 | 28 | Class parameterType = method.getParameterTypes()[0]; 29 | if (parameterType.isArray() || method.isVarArgs()) { 30 | System.out.println(method.getName() + " has @Subscribe annotation, " + 31 | "but its parameter should not be an array or varargs."); 32 | } 33 | 34 | method.setAccessible(true); 35 | ListenerMethod listenerMethod = new ListenerMethod(method, method.getParameterTypes()[0]); 36 | listenerMethodList.add(listenerMethod); 37 | } 38 | } 39 | 40 | if (subscribedClass.getSuperclass() != null && !subscribedClass.getSuperclass().equals(Object.class)) { 41 | List subscribedMethods = findSubscribedMethods(subscribedClass.getSuperclass()); 42 | listenerMethodList.addAll(subscribedMethods); 43 | } 44 | 45 | if (subscribedClass.getInterfaces() != null && subscribedClass.getInterfaces().length > 0) { 46 | for (Class interfaceClass : subscribedClass.getInterfaces()) { 47 | List subscribedMethods = findSubscribedMethods(interfaceClass); 48 | listenerMethodList.addAll(subscribedMethods); 49 | } 50 | } 51 | } 52 | return listenerMethodList; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /event-driven-arch-pattern/com/alg/ap/eventdriven2/Subscribe.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.eventdriven2; 2 | 3 | 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | /** 10 | * Makes a method eligible to respond to an event. 11 | * 12 | * It should be applied to a method (with any access modifier) which has 13 | * only one argument with the type of the event. If it is applied on a method 14 | * having no parameter or more than one parameters, during registration,an exception will be thrown 15 | * 16 | * If a method in an interface or an abstract class is marked with this annotation, 17 | * all the overridden methods will be eligible for subscription. 18 | */ 19 | @Retention(RetentionPolicy.RUNTIME) 20 | @Target({ElementType.METHOD}) 21 | public @interface Subscribe { 22 | 23 | } 24 | -------------------------------------------------------------------------------- /event-driven-arch-pattern/com/alg/ap/eventdriven2/Subscriber1.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.eventdriven2; 2 | 3 | public class Subscriber1 { 4 | private EventBus eventBus; 5 | 6 | public Subscriber1(EventBus eventBus) { 7 | super(); 8 | this.eventBus = eventBus; 9 | eventBus.register(this); 10 | } 11 | 12 | public void push() throws Exception { 13 | eventBus.post(""); 14 | } 15 | 16 | @Subscribe 17 | public void receive(String event) { 18 | 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /event-driven-arch-pattern/com/alg/ap/events/CircularShifter.java: -------------------------------------------------------------------------------- 1 | 2 | 3 | package com.alg.ap.events; 4 | 5 | public class CircularShifter extends Thread { 6 | private EventManager eventManager; 7 | private String id; 8 | 9 | public CircularShifter(EventManager eventManager, String id) { 10 | super(); 11 | this.eventManager = eventManager; 12 | eventManager.register(id); 13 | this.id = id; 14 | } 15 | 16 | public void run() { 17 | while (true) { 18 | Event event = eventManager.getEvent(id); 19 | System.out.println("shifter received event" + event); 20 | if (event == null) { 21 | try { 22 | Thread.sleep(1000); 23 | } catch (Exception e) { 24 | } 25 | continue; 26 | } 27 | if (event.getId() == -1) { 28 | event.setSourceid(id); 29 | eventManager.postEvent(event); 30 | break; 31 | } 32 | String line = event.getMessage(); 33 | int nshifts = line.split(" ").length; 34 | for (int i = 0; i < nshifts; ++i) { 35 | Event shift_event = new Event(); 36 | int pos = line.indexOf(' '); 37 | String current = line.substring(0, pos); 38 | String tmp = line.substring(pos + 1) + " " + current; 39 | shift_event.setId(i); 40 | shift_event.setMessage(tmp); 41 | shift_event.setSourceid(id); 42 | eventManager.postEvent(shift_event); 43 | System.out.println("Shifter is posting event:" + shift_event); 44 | line = tmp; 45 | } 46 | } 47 | 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /event-driven-arch-pattern/com/alg/ap/events/Driver.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.events; 2 | 3 | public class Driver { 4 | 5 | public static void main(String[] args) { 6 | EventManager eventManager = new EventManager(); 7 | InputReader ir = new InputReader(eventManager, args[0], "ir"); 8 | CircularShifter shifter = new CircularShifter(eventManager, "cs"); 9 | Sorter sorter = new Sorter(eventManager, "sorter"); 10 | OutputWriter ow = new OutputWriter(eventManager, args[1],"ow"); 11 | ir.start(); 12 | shifter.start(); 13 | sorter.start(); 14 | ow.start(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /event-driven-arch-pattern/com/alg/ap/events/Event.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.events; 2 | 3 | public class Event { 4 | private int id; 5 | private String sourceid; 6 | private String message; 7 | 8 | public Event() { 9 | super(); 10 | // TODO Auto-generated constructor stub 11 | } 12 | 13 | public Event(int id, String sourceid, String message) { 14 | super(); 15 | this.id = id; 16 | this.sourceid = sourceid; 17 | this.message = message; 18 | } 19 | 20 | public int getId() { 21 | return id; 22 | } 23 | 24 | public String getSourceid() { 25 | return sourceid; 26 | } 27 | 28 | public String getMessage() { 29 | return message; 30 | } 31 | 32 | public void setId(int id) { 33 | this.id = id; 34 | } 35 | 36 | public void setSourceid(String sourceid) { 37 | this.sourceid = sourceid; 38 | } 39 | 40 | public void setMessage(String message) { 41 | this.message = message; 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return "Event [id=" + id + ", sourceid=" + sourceid + ", message=" 47 | + message + "]"; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /event-driven-arch-pattern/com/alg/ap/events/EventManager.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.events; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import java.util.Map.Entry; 6 | 7 | public class EventManager implements IEventManager { 8 | private Map event_queues; 9 | 10 | public EventManager() { 11 | event_queues = new HashMap(); 12 | } 13 | 14 | @Override 15 | public synchronized void register(String name) { 16 | event_queues.put(name, new EventQueue(name)); 17 | } 18 | 19 | @Override 20 | public synchronized void unregister(String id) { 21 | for(String eq:event_queues.keySet()) { 22 | if(eq.equals(id)) 23 | event_queues.remove(eq); 24 | } 25 | } 26 | 27 | @Override 28 | public synchronized void postEvent(Event event) { 29 | for(Entry entry:event_queues.entrySet()) { 30 | if(entry.getKey().equals(event.getSourceid())) 31 | entry.getValue().addEvent(event); 32 | } 33 | 34 | } 35 | 36 | @Override 37 | public Event getEvent(String id) { 38 | if(id.equals("cs")) 39 | id = "ir"; 40 | else if(id.equals("sorter")) 41 | id = "cs"; 42 | else if(id.equals(("ow"))) 43 | id = "sorter"; 44 | return event_queues.get(id).fetchEvent(); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /event-driven-arch-pattern/com/alg/ap/events/EventQueue.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.events; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class EventQueue { 7 | private String id; 8 | private List events; 9 | 10 | public EventQueue(String id) { 11 | this.id = id; 12 | events = new ArrayList(); 13 | } 14 | 15 | public String getId() { 16 | return id; 17 | } 18 | 19 | public void addEvent(Event e) { 20 | events.add(e); 21 | } 22 | 23 | public Event fetchEvent() { 24 | if(events.size() == 0) return null; 25 | return events.remove(0); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /event-driven-arch-pattern/com/alg/ap/events/IEventManager.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.events; 2 | 3 | public interface IEventManager { 4 | void register(String id); 5 | void unregister(String id); 6 | void postEvent(Event event); 7 | Event getEvent(String id); 8 | } 9 | -------------------------------------------------------------------------------- /event-driven-arch-pattern/com/alg/ap/events/InputReader.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.events; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.FileReader; 5 | 6 | public class InputReader extends Thread { 7 | private EventManager eventManager; 8 | private String infile; 9 | private String id; 10 | 11 | public InputReader(EventManager eventManager, String infile, String id) { 12 | this.eventManager = eventManager; 13 | eventManager.register(id); 14 | this.id = id; 15 | this.infile = infile; 16 | } 17 | 18 | public void run() { 19 | try { 20 | BufferedReader br = new BufferedReader(new FileReader(infile)); 21 | String line; 22 | int count = 0; 23 | while ((line = br.readLine()) != null) { 24 | Event event = new Event(++count, id, line); 25 | System.out.println("Input reader is posting event:" + event); 26 | eventManager.postEvent(event); 27 | } 28 | Event event = new Event(-1,id, null); 29 | eventManager.postEvent(event); 30 | System.out.println("Input reader is posting event:" + event); 31 | } catch (Exception e) { 32 | System.out.println(e); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /event-driven-arch-pattern/com/alg/ap/events/OutputWriter.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.events; 2 | 3 | import java.io.BufferedWriter; 4 | import java.io.FileWriter; 5 | 6 | public class OutputWriter extends Thread { 7 | private EventManager eventManager; 8 | private String outfile; 9 | private String id; 10 | 11 | public OutputWriter(EventManager eventManager, String outfile, String id) { 12 | this.eventManager = eventManager; 13 | eventManager.register(id); 14 | this.id = id; 15 | this.outfile = outfile; 16 | } 17 | 18 | public void run() { 19 | try { 20 | BufferedWriter bw = new BufferedWriter(new FileWriter(outfile)); 21 | while (true) { 22 | Event event = eventManager.getEvent(id); 23 | System.out.println("Output writer receiving event:" + event); 24 | if (event == null) { 25 | try { 26 | Thread.sleep(1000); 27 | } catch (Exception e) { 28 | } 29 | continue; 30 | } 31 | if (event.getId() == -1) { 32 | bw.close(); 33 | break; 34 | } 35 | bw.write(event.getMessage()); 36 | bw.newLine(); 37 | } 38 | } catch (Exception e) { 39 | System.out.println(e); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /event-driven-arch-pattern/com/alg/ap/events/Sorter.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.events; 2 | 3 | import java.util.TreeSet; 4 | 5 | public class Sorter extends Thread { 6 | private TreeSet sorted_lines; 7 | private EventManager eventManager; 8 | private String id; 9 | 10 | public Sorter(EventManager eventManager, String id) { 11 | sorted_lines = new TreeSet(); 12 | this.eventManager = eventManager; 13 | this.id = id; 14 | eventManager.register(id); 15 | } 16 | 17 | public void run() { 18 | int count = 0; 19 | while (true) { 20 | Event event = eventManager.getEvent(id); 21 | System.out.println("Sorter receiving event:" + event); 22 | if(event == null) { 23 | try { 24 | Thread.sleep(1000); 25 | } catch (Exception e) { 26 | } 27 | continue; 28 | } 29 | if (event.getId() == -1) { 30 | for (String tmp : sorted_lines) { 31 | Event event2 = new Event(++count, id, tmp); 32 | eventManager.postEvent(event2); 33 | System.out.println("Sorter posting event:" + event2); 34 | } 35 | event.setSourceid(id); 36 | eventManager.postEvent(event); 37 | System.out.println("Sorter posting event:" + event); 38 | break; 39 | } 40 | sorted_lines.add(event.getMessage()); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /main-subroutine-arch-pattern/com/alg/ap/procedural/Driver.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.procedural; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.BufferedWriter; 5 | import java.io.FileReader; 6 | import java.io.FileWriter; 7 | import java.util.ArrayList; 8 | import java.util.Collections; 9 | import java.util.List; 10 | 11 | public class Driver { 12 | static List lines = new ArrayList(); 13 | static List shifted_lines = new ArrayList(); 14 | 15 | public static void readInput(String infile) throws Exception { 16 | BufferedReader br = new BufferedReader(new BufferedReader( 17 | new FileReader(infile))); 18 | String line; 19 | while ((line = br.readLine()) != null) 20 | lines.add(line); 21 | br.close(); 22 | } 23 | 24 | public static void circularShift() { 25 | for (String line : lines) { 26 | int nshifts = line.split(" ").length; 27 | for (int i = 0; i < nshifts; ++i) { 28 | int pos = line.indexOf(' '); 29 | String current = line.substring(0, pos); 30 | String tmp = line.substring(pos+1) + " " + current; 31 | shifted_lines.add(tmp); 32 | line = tmp; 33 | } 34 | } 35 | } 36 | 37 | public static void sort() { 38 | Collections.sort(shifted_lines); 39 | } 40 | 41 | public static void writeOutput(String outfile) throws Exception { 42 | BufferedWriter bw = new BufferedWriter(new FileWriter(outfile)); 43 | for(String line: shifted_lines) { 44 | bw.write(line); 45 | bw.newLine(); 46 | } 47 | bw.close(); 48 | } 49 | 50 | public static void main(String[] args) throws Exception { 51 | readInput(args[0]); 52 | System.out.println(lines); 53 | circularShift(); 54 | System.out.println(shifted_lines); 55 | sort(); 56 | System.out.println(shifted_lines); 57 | writeOutput(args[1]); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /oo-arch-pattern/com/alg/ap/oostyle/CircularShifter.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.oostyle; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | public class CircularShifter { 7 | List shifted_lines = new ArrayList(); 8 | 9 | public void circularShift(List lines) { 10 | for (String line : lines) { 11 | int nshifts = line.split(" ").length; 12 | for (int i = 0; i < nshifts; ++i) { 13 | int pos = line.indexOf(' '); 14 | String current = line.substring(0, pos); 15 | String tmp = line.substring(pos+1) + " " + current; 16 | shifted_lines.add(tmp); 17 | line = tmp; 18 | } 19 | } 20 | } 21 | 22 | public List getShiftedLines() { 23 | return shifted_lines; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /oo-arch-pattern/com/alg/ap/oostyle/Driver.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.oostyle; 2 | 3 | public class Driver { 4 | 5 | public static void main(String[] args) throws Exception { 6 | InputReader ir = new InputReader(); 7 | ir.readInput(args[0]); 8 | CircularShifter shifter = new CircularShifter(); 9 | shifter.circularShift(ir.getLines()); 10 | Sorter sorter = new Sorter(); 11 | sorter.sort(shifter.getShiftedLines()); 12 | OutputWriter ow = new OutputWriter(); 13 | ow.writeOuput(sorter.getSortedShiftedLines(), args[1]); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /oo-arch-pattern/com/alg/ap/oostyle/InputReader.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.oostyle; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.FileReader; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class InputReader { 9 | private List lines = new ArrayList(); 10 | 11 | public void readInput(String infile) throws Exception { 12 | BufferedReader br = new BufferedReader(new BufferedReader( 13 | new FileReader(infile))); 14 | String line; 15 | while ((line = br.readLine()) != null) 16 | lines.add(line); 17 | br.close(); 18 | } 19 | 20 | //TODO: replace it with iterator pattern 21 | public List getLines() { 22 | return lines; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /oo-arch-pattern/com/alg/ap/oostyle/OutputWriter.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.oostyle; 2 | 3 | import java.io.BufferedWriter; 4 | import java.io.FileWriter; 5 | import java.util.List; 6 | 7 | public class OutputWriter { 8 | 9 | public void writeOuput(List sorted_shifted_lines, String outfile) 10 | throws Exception { 11 | BufferedWriter bw = new BufferedWriter(new FileWriter(outfile)); 12 | for (String line : sorted_shifted_lines) { 13 | bw.write(line); 14 | bw.newLine(); 15 | } 16 | bw.close(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /oo-arch-pattern/com/alg/ap/oostyle/Sorter.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.oostyle; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.List; 6 | 7 | public class Sorter { 8 | private List sorted_shifted_lines; 9 | 10 | public void sort(List shifted_lines) { 11 | sorted_shifted_lines = new ArrayList(shifted_lines); 12 | Collections.sort(sorted_shifted_lines); 13 | } 14 | 15 | public List getSortedShiftedLines() { 16 | return sorted_shifted_lines; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pipe-filter-arch-pattern/com/alg/ap/pipefilter/CircularShifterFilter.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.pipefilter; 2 | 3 | import java.io.DataInputStream; 4 | import java.io.PrintStream; 5 | 6 | public class CircularShifterFilter extends Filter { 7 | 8 | public void run() { 9 | try { 10 | PrintStream ps = new PrintStream(getOutputWriterPort()); 11 | DataInputStream dis = new DataInputStream(getInputReadPort()); 12 | String line; 13 | System.out.println("Circular Shifter Filter Started"); 14 | while((line = dis.readLine()) != null) { 15 | int nshifts = line.split(" ").length; 16 | for (int i = 0; i < nshifts; ++i) { 17 | int pos = line.indexOf(' '); 18 | String current = line.substring(0, pos); 19 | String tmp = line.substring(pos + 1) + " " + current; 20 | ps.println(tmp); 21 | System.out.println("Circular Shifter Filter:" + tmp); 22 | line = tmp; 23 | } 24 | } 25 | closePorts(); 26 | ps.close(); 27 | dis.close(); 28 | } catch (Exception e) { 29 | System.out.println(e); 30 | closePorts(); 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /pipe-filter-arch-pattern/com/alg/ap/pipefilter/Driver.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.pipefilter; 2 | 3 | public class Driver { 4 | public static void main( String[] args) { 5 | InputReaderFilter irfilter = new InputReaderFilter(args[0]); 6 | CircularShifterFilter csfilter = new CircularShifterFilter(); 7 | SorterFilter sortfilter = new SorterFilter(); 8 | OutputWriterFilter owfilter = new OutputWriterFilter(args[1]); 9 | 10 | owfilter.connect(sortfilter); 11 | sortfilter.connect(csfilter); 12 | csfilter.connect(irfilter); 13 | 14 | irfilter.start(); 15 | csfilter.start(); 16 | sortfilter.start(); 17 | owfilter.start(); 18 | } 19 | } -------------------------------------------------------------------------------- /pipe-filter-arch-pattern/com/alg/ap/pipefilter/Filter.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.pipefilter; 2 | 3 | import java.io.*; 4 | 5 | public class Filter extends Thread { 6 | private PipedInputStream inputReadPort = new PipedInputStream(); 7 | private PipedOutputStream outputWritePort = new PipedOutputStream(); 8 | //private Filter inputFilter; 9 | 10 | public void connect(Filter filter) { 11 | try { 12 | inputReadPort.connect( filter.getOutputWriterPort() ); 13 | //inputFilter = Filter; 14 | 15 | } catch(Exception e ) { 16 | System.out.println(e); 17 | 18 | } 19 | 20 | } 21 | 22 | public void closePorts() { 23 | try { 24 | inputReadPort.close(); 25 | outputWritePort.close(); 26 | } catch( Exception e ) { 27 | System.out.println(e); 28 | } 29 | 30 | } 31 | 32 | public PipedInputStream getInputReadPort() { 33 | return inputReadPort; 34 | } 35 | 36 | public PipedOutputStream getOutputWriterPort() { 37 | return outputWritePort; 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /pipe-filter-arch-pattern/com/alg/ap/pipefilter/InputReaderFilter.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.pipefilter; 2 | 3 | import java.io.*; 4 | 5 | public class InputReaderFilter extends Filter { 6 | private String infile; 7 | 8 | public InputReaderFilter(String infile) { 9 | this.infile = infile; 10 | } 11 | 12 | public void run() { 13 | try { 14 | BufferedReader br = new BufferedReader(new BufferedReader( 15 | new FileReader(infile))); 16 | String line; 17 | PrintStream ps = new PrintStream(getOutputWriterPort()); 18 | System.out.println("Input Reader filter started"); 19 | while ((line = br.readLine()) != null) { 20 | System.out.println("Input reader Filter: " + line); 21 | ps.println(line); 22 | //ps.flush(); 23 | } 24 | closePorts(); 25 | br.close(); 26 | ps.close(); 27 | } catch (Exception e) { 28 | System.out.println(e); 29 | closePorts(); 30 | } 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /pipe-filter-arch-pattern/com/alg/ap/pipefilter/OutputWriterFilter.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.pipefilter; 2 | 3 | import java.io.BufferedWriter; 4 | import java.io.DataInputStream; 5 | import java.io.FileWriter; 6 | 7 | public class OutputWriterFilter extends Filter { 8 | private String outfile; 9 | 10 | public OutputWriterFilter(String outfile) { 11 | this.outfile = outfile; 12 | } 13 | 14 | public void run() { 15 | try { 16 | BufferedWriter bw = new BufferedWriter(new FileWriter(outfile)); 17 | DataInputStream dis = new DataInputStream(getInputReadPort()); 18 | String line; 19 | System.out.println("Output writer filter started"); 20 | while((line = dis.readLine()) != null) { 21 | System.out.println("Output writer filter:" + line); 22 | bw.write(line); 23 | bw.newLine(); 24 | } 25 | closePorts(); 26 | bw.close(); 27 | dis.close(); 28 | } catch (Exception e) { 29 | System.out.println(e); 30 | closePorts(); 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /pipe-filter-arch-pattern/com/alg/ap/pipefilter/SorterFilter.java: -------------------------------------------------------------------------------- 1 | package com.alg.ap.pipefilter; 2 | 3 | import java.io.DataInputStream; 4 | import java.io.PrintStream; 5 | import java.util.TreeSet; 6 | 7 | public class SorterFilter extends Filter { 8 | private TreeSet sorted_lines = new TreeSet(); 9 | 10 | public void run() { 11 | try { 12 | PrintStream ps = new PrintStream(getOutputWriterPort()); 13 | DataInputStream dis = new DataInputStream(getInputReadPort()); 14 | String line; 15 | System.out.println("Sorter Filter started"); 16 | while((line = dis.readLine()) != null) { 17 | System.out.println("Sorter Filter:" + line); 18 | sorted_lines.add(line); 19 | } 20 | for(String line1: sorted_lines) 21 | ps.println(line1); 22 | closePorts(); 23 | ps.close(); 24 | dis.close(); 25 | } catch (Exception e) { 26 | System.out.println(e); 27 | closePorts(); 28 | } 29 | } 30 | } 31 | --------------------------------------------------------------------------------