/**
* =========================================================================
* __ ____ ____ __ ____ ___ __ __ ____ ____ ____
* || || \\ || (( \ || \\ // \\ ||\ || || \\ || || \\
* || ||_// ||== \\ ||_// (( )) ||\\|| || )) ||== ||_//
* |__|| || \\ ||___ \_)) || \\_// || \|| ||_// ||___ || \\
* =========================================================================
*
* Copyright 2012 Brad Peabody
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* =========================================================================
*/
package org.jresponder.message;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
/**
* Default message group implementation. Normally gets created via
* Spring config.
*
* @author bradpeabody
*
*/
public class MessageGroupImpl implements MessageGroup, InitializingBean, BeanNameAware {
/* ====================================================================== */
/* Logger boiler plate */
/* ====================================================================== */
private static Logger l = null;
private Logger logger() { if (l == null) l = LoggerFactory.getLogger(this.getClass()); return l; }
/* ====================================================================== */
private static final String OPT_IN_CONFIRM_NAME = "opt-in-confirm";
private static final String HTML_EXT = ".html";
private String name;
private String description;
private List<MessageRef> messageRefList;
private File directory;
private MessageRef optInConfirmMessageRef;
/** checksum of messageRefList so we can see if it changed */
private String messageRefListChecksum = "";
@Override
public String getName() {
return name;
}
public void setId(String v) {
name = v;
}
@Override
public void setBeanName(String aBeanName) {
name = aBeanName;
}
@Override
public String getDescription() {
return description;
}
public void setDescription(String v) {
description = v;
}
@Override
public List<MessageRef> getMessageRefList() {
return messageRefList;
}
public void setMessageRefs(List<MessageRef> v) {
messageRefList = v;
}
@Override
public int indexOfName(String aName) {
if (aName == null) { return -1; }
int i = 0;
for (MessageRef myMessageRef: messageRefList) {
if (aName.equals(myMessageRef.getName())) {
return i;
}
i++;
}
return -1;
}
@Override
public MessageRef getMessageRefByName(String aId) {
if (aId == null) return null;
for (MessageRef myMessageRef: messageRefList) {
if (aId.equals(myMessageRef.getName())) {
return myMessageRef;
}
}
return null;
}
@Override
public MessageRef getOptInConfirmMessageRef() {
return optInConfirmMessageRef;
}
public File getDirectory() {
return directory;
}
/**
* The directory to read message refs from
* @param directory
*/
public void setDirectory(File directory) {
this.directory = directory;
}
/**
* Call after set properties, performs the actual
* loading from the directory.
*/
@Override
public void afterPropertiesSet() throws Exception {
refresh();
}
@Override
public void refresh() {
if (directory == null) {
throw new IllegalStateException("directory cannot be null");
}
logger().debug("MessageGroupImpl - Starting refresh with directory: {}", directory.getAbsolutePath());
// update checksum so conditionalRefresh() can do it's thing
messageRefListChecksum = calcChecksum();
File[] myFiles = directory.listFiles();
messageRefList = new ArrayList<MessageRef>();
for (File myFile: myFiles) {
if (myFile.isFile()) {
if (myFile.getName().endsWith(HTML_EXT)) {
try {
MessageRefImpl myMessageRefImpl;
myMessageRefImpl = new MessageRefImpl(myFile);
// call this so that it errors now instead of later -
// this way the sending engine doesn't have to have
// complicated logic to deal with a badly formatted
// message wait value
myMessageRefImpl.getWaitAfterLastMessage();
// the "opt-in-confirm" message is treated differently
if (myMessageRefImpl.getName().equals(OPT_IN_CONFIRM_NAME)) {
optInConfirmMessageRef = myMessageRefImpl;
}
else {
messageRefList.add(myMessageRefImpl);
}
} catch (Throwable e) {
// if an error occurs parsing a message, don't
// assume all is lost, log error and continue
logger().error(e.getMessage(), e);
}
}
}
}
// done!
}
protected String calcChecksum() {
StringBuilder myStringBuilder = new StringBuilder();
File[] myFiles = directory.listFiles();
for (File myFile: myFiles) {
if (myFile.isFile()) {
if (myFile.getName().endsWith(HTML_EXT) && !(myFile.getName().equals(OPT_IN_CONFIRM_NAME+HTML_EXT))) {
myStringBuilder
.append(myFile.getName())
// don't include date, just want the message list
//.append("|")
//.append(myFile.lastModified())
.append("|");
}
}
}
return myStringBuilder.toString();
}
@Override
public boolean conditionalRefresh() {
String myChecksum = calcChecksum();
if (myChecksum.equals(messageRefListChecksum)) {
try {
boolean myChanged = false;
// if checksum is not changed, then just call
// conditionalRefresh on each messageref
for (MessageRef myMessageRef: messageRefList) {
if (myMessageRef.conditionalRefresh()) {
myChanged = true;
}
}
if (optInConfirmMessageRef.conditionalRefresh()) {
myChanged = true;
}
return myChanged;
} catch (InvalidMessageException e) {
throw new RuntimeException(e);
}
}
refresh();
return true;
}
}