BrightSide Workbench Full Report + Source Code
MessageQueue.java
Go to the documentation of this file.
1 /*
2  * TurrĂ³ i Cutiller Foundation. License notice.
3  * Copyright (C) 2021 Lluis TurrĂ³ Cutiller <http://www.turro.org/>
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Affero General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Affero General Public License for more details.
14  *
15  * You should have received a copy of the GNU Affero General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 package org.turro.message;
20 
21 import java.io.IOException;
22 import java.nio.file.FileSystems;
23 import java.nio.file.Files;
24 import java.nio.file.Path;
25 import java.nio.file.PathMatcher;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.Set;
29 import java.util.concurrent.BlockingQueue;
30 import java.util.concurrent.ConcurrentHashMap;
31 import java.util.concurrent.ConcurrentMap;
32 import java.util.concurrent.LinkedBlockingQueue;
33 import java.util.logging.Level;
34 import java.util.logging.Logger;
35 import java.util.stream.Stream;
36 import org.turro.string.Strings;
37 import org.turro.collections.KeyValueMap;
38 import org.turro.elephant.context.ElephantContext;
39 import org.turro.elephant.context.IConstructor;
40 import org.turro.elephant.direct.AbstractDirectContentCtrl;
41 import org.turro.elephant.direct.DirectContent;
42 import org.turro.elephant.impl.util.FileUtil;
43 import org.turro.marker.ElephantMarker;
44 import org.turro.plugin.contacts.IContact;
45 
50 @DirectContent(identifier="message-queue")
52 
53  public static void pushMessage(IContact contact, String msg) {
54  getQueue(contact).add(msg);
55  }
56 
57  public static String pollMessage(IContact contact) {
58  return getQueue(contact).poll();
59  }
60 
61  public static boolean hasMessage(IContact contact) {
62  return !(getQueue(contact).isEmpty());
63  }
64 
65  public static void pushMessage(String idContact, String msg) {
66  getQueue(idContact).add(msg);
67  }
68 
69  public static String pollMessage(String idContact) {
70  return getQueue(idContact).poll();
71  }
72 
73  public static boolean hasMessage(String idContact) {
74  return !(getQueue(idContact).isEmpty());
75  }
76 
77  public String getIntervalCall(IConstructor constructor) {
78  IContact user = constructor.getUser();
79  if(user != null) {
80  KeyValueMap map = new KeyValueMap();
81  map.put("userId", user.getId());
82  map.put("type", "query");
83  return getAjaxEvalUrl(map);
84  } else {
85  return null;
86  }
87  }
88 
89  /* Generic message */
90 
91  private static final String GENERIC_MESSAGE_FOLDER = "/WEB-INF/elephant/message";
92 
93  public static void pushGenerics(String idContact) {
94  Path folder = Path.of(ElephantContext.getRealPath(GENERIC_MESSAGE_FOLDER));
95  if(Files.exists(folder)) {
96  PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:**.txt");
97  try (Stream<Path> entries = Files.list(folder).filter(p -> matcher.matches(p))) {
98  entries.forEach(file -> {
99  try {
100  pushMessage(idContact, FileUtil.getContent(file.toFile()));
101  } catch (IOException ex) {
102  Logger.getLogger(MessageQueue.class.getName()).log(Level.SEVERE, ElephantContext.logMsg(null), ex);
103  }
104  });
105  } catch (IOException ex) {
106  Logger.getLogger(MessageQueue.class.getName()).log(Level.SEVERE, ElephantContext.logMsg(null), ex);
107  }
108  }
109  }
110 
111  /* Queue map */
112 
113  private static final ConcurrentMap<String, BlockingQueue<String>> QUEUE_MAP = new ConcurrentHashMap<>();
114 
115  public static BlockingQueue<String> getQueue(IContact contact) {
116  return getQueue(contact.getId());
117  }
118 
119  public static BlockingQueue<String> getQueue(String idContact) {
120  return QUEUE_MAP.computeIfAbsent(idContact, k -> new LinkedBlockingQueue<String>());
121  }
122 
123  /* DirectContent */
124 
125  public MessageQueue() {
126  super("widgets/messages");
127  setNeedsUser(true);
128  }
129 
130  @Override
131  protected String getIdentifier() {
132  return MessageQueue.class.getAnnotation(DirectContent.class).identifier();
133  }
134 
135  @Override
136  protected void prepareMarker(ElephantMarker marker) {
137  setTemplate("init");
138  }
139 
140  @Override
141  protected void prepareCleanMarker(ElephantMarker marker, KeyValueMap map) {
142  setTemplate("toast");
143  marker.putAll(map);
144  }
145 
146  @Override
147  protected void doExecute(IConstructor constructor, KeyValueMap map) {
148  String type = map.get("type"),
149  userId = map.get("userId");
150  if("query".equals(type) && !Strings.isBlank(userId)) {
151  Set<String> messages = new HashSet<>();
152  while(hasMessage(userId)) {
153  messages.add(pollMessage(userId));
154  }
155  if(!messages.isEmpty()) {
156  HashMap extra = new HashMap();
157  extra.put("messages", messages);
158  writeMarkerToResponse(constructor, map, extra);
159  }
160  }
161  }
162 
163 }
static String getContent(File file)
Definition: FileUtil.java:245
static void pushGenerics(String idContact)
static void pushMessage(IContact contact, String msg)
void prepareCleanMarker(ElephantMarker marker, KeyValueMap map)
static boolean hasMessage(IContact contact)
String getIntervalCall(IConstructor constructor)
static void pushMessage(String idContact, String msg)
static BlockingQueue< String > getQueue(IContact contact)
static String pollMessage(String idContact)
void doExecute(IConstructor constructor, KeyValueMap map)
static String pollMessage(IContact contact)
void prepareMarker(ElephantMarker marker)
static BlockingQueue< String > getQueue(String idContact)
static boolean hasMessage(String idContact)