package org.jtheque.events.impl; import org.jtheque.events.Event; import org.jtheque.events.EventLevel; import org.jtheque.events.EventService; import org.jtheque.events.Events; import org.jtheque.utils.StringUtils; import org.jtheque.utils.SystemProperty; import org.jtheque.utils.ThreadUtils; import org.jtheque.utils.annotations.GuardedInternally; import org.jtheque.utils.annotations.ThreadSafe; import org.jtheque.utils.collections.CollectionUtils; import org.jtheque.utils.io.FileUtils; import org.jtheque.xml.utils.XML; import org.jtheque.xml.utils.XMLException; import org.jtheque.xml.utils.XMLOverReader; import org.jtheque.xml.utils.XMLWriter; import org.slf4j.LoggerFactory; import org.w3c.dom.Node; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import java.io.File; import java.util.Collection; import java.util.Date; import java.util.Map; /* * Copyright JTheque (Baptiste Wicht) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * An event manager implementation. * * @author Baptiste Wicht */ @ThreadSafe public final class EventServiceImpl implements EventService { private final File eventsFile = new File(SystemProperty.USER_DIR.get(), "core/logs.xml"); @GuardedInternally private final Map<String, Collection<Event>> logs = CollectionUtils.newConcurrentMap(5); /** * Construct a new EventServiceImpl. */ public EventServiceImpl() { super(); logs.put(CORE_EVENT_LOG, CollectionUtils.<Event>newSet(50)); } @Override public Collection<String> getEventLogs() { return CollectionUtils.protect(logs.keySet()); } @Override public Collection<Event> getEvents(String log) { return CollectionUtils.protect(logs.get(log)); } @Override public void addEvent(Event event) { synchronized (this) { if (!logs.containsKey(event.getLog())) { logs.put(event.getLog(), CollectionUtils.<Event>newList(25)); } logs.get(event.getLog()).add(event); } } /** * Import from XML. The import is made asynchronously to avoid making the application pause during launching. */ @PostConstruct public void importFromXML() { if (eventsFile.exists()) { ThreadUtils.inNewThread(new Runnable() { @Override public void run() { readEvents(eventsFile); } }); } } /** * Read all the events from the file. * * @param f The file to read events from. */ private void readEvents(File f) { XMLOverReader reader = XML.newJavaFactory().newOverReader(); try { reader.openFile(f); while (reader.next("log")) { String name = reader.readString("@name"); Collection<Event> events = CollectionUtils.newList(50); while (reader.next("event")) { events.add(Events.newEvent( EventLevel.get(reader.readInt("@level")), new Date(reader.readLong("@date")), reader.readString("@source"), reader.readString("@title"), reader.readString("@details"), name)); } logs.put(name, events); } } catch (XMLException e) { LoggerFactory.getLogger(getClass()).error(e.getMessage(), e); } finally { FileUtils.close(reader); } } /** * Save the events to XML. */ @PreDestroy public void saveXML() { XMLWriter<Node> writer = XML.newJavaFactory().newWriter("logs"); for (Map.Entry<String, Collection<Event>> entry : logs.entrySet()) { writer.add("log"); writer.addAttribute("name", entry.getKey()); writeEvents(writer, entry.getValue()); writer.switchToParent(); } writer.write(eventsFile.getAbsolutePath()); } /** * Write the events to the XML file. * * @param writer The writer to use. * @param events The logs to write. */ private static void writeEvents(XMLWriter<Node> writer, Iterable<Event> events) { for (Event event : events) { writer.add("event"); writer.addAttribute("level", Integer.toString(event.getLevel().intValue())); writer.addAttribute("date", Long.toString(event.getDate().getTime())); writer.addAttribute("source", event.getSource()); writer.addAttribute("title", event.getTitleKey()); if (StringUtils.isNotEmpty(event.getDetailsKey())) { writer.addAttribute("details", event.getDetailsKey()); } writer.switchToParent(); } } }