NIHVIVO-1229 Create the RevisionInfoBean, with setup listener and unit tests.
This commit is contained in:
parent
bc86f50c5b
commit
b438f7d36d
6 changed files with 860 additions and 11 deletions
|
@ -0,0 +1,202 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.config;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import com.ibm.icu.text.SimpleDateFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information about the provenance of this application: release, revision
|
||||||
|
* level, build date, etc.
|
||||||
|
*
|
||||||
|
* Except for the build date, the information is stored for all levels of the
|
||||||
|
* application. So an instance of NIHVIVO might read:
|
||||||
|
*
|
||||||
|
* date: 2010-11-09 12:15:44
|
||||||
|
*
|
||||||
|
* level: vitro-core, trunk, 1234:1236M
|
||||||
|
*
|
||||||
|
* level: vivo, branch rel_1.1_maint, 798
|
||||||
|
*
|
||||||
|
* Note that the levels should be listed from inner to outer.
|
||||||
|
*
|
||||||
|
* Instances of this class are immutable.
|
||||||
|
*/
|
||||||
|
public class RevisionInfoBean {
|
||||||
|
private static final Log log = LogFactory.getLog(RevisionInfoBean.class);
|
||||||
|
|
||||||
|
/** A dummy bean to use if there is no real one. */
|
||||||
|
static final RevisionInfoBean DUMMY_BEAN = new RevisionInfoBean(
|
||||||
|
new Date(0), Collections.singleton(LevelRevisionInfo.DUMMY_LEVEL));
|
||||||
|
|
||||||
|
/** The bean is attached to the session by this name. */
|
||||||
|
static final String ATTRIBUTE_NAME = RevisionInfoBean.class.getName();
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// static methods
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/** Package access: should only be used during setup. */
|
||||||
|
static void setBean(ServletContext context, RevisionInfoBean bean) {
|
||||||
|
if (bean == null) {
|
||||||
|
bean = DUMMY_BEAN;
|
||||||
|
}
|
||||||
|
context.setAttribute(ATTRIBUTE_NAME, bean);
|
||||||
|
log.info(bean);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static RevisionInfoBean getBean(HttpSession session) {
|
||||||
|
if (session == null) {
|
||||||
|
log.warn("Tried to get revision info bean with a null session!");
|
||||||
|
return DUMMY_BEAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object o = session.getServletContext().getAttribute(ATTRIBUTE_NAME);
|
||||||
|
if (o == null) {
|
||||||
|
log.warn("Tried to get revision info bean, but didn't find any.");
|
||||||
|
return DUMMY_BEAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(o instanceof RevisionInfoBean)) {
|
||||||
|
log.error("Tried to get revision info bean, but found an instance of "
|
||||||
|
+ o.getClass().getName() + ": " + o);
|
||||||
|
return DUMMY_BEAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (RevisionInfoBean) o;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void removeBean(ServletContext context) {
|
||||||
|
context.removeAttribute(ATTRIBUTE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// the bean
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
private final long buildDate;
|
||||||
|
private final List<LevelRevisionInfo> levelInfos;
|
||||||
|
|
||||||
|
public RevisionInfoBean(Date buildDate,
|
||||||
|
Collection<LevelRevisionInfo> levelInfos) {
|
||||||
|
this.buildDate = buildDate.getTime();
|
||||||
|
this.levelInfos = Collections
|
||||||
|
.unmodifiableList(new ArrayList<LevelRevisionInfo>(levelInfos));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getBuildDate() {
|
||||||
|
return new Date(buildDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<LevelRevisionInfo> getLevelInfos() {
|
||||||
|
return levelInfos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getReleaseLabel() {
|
||||||
|
if (levelInfos.isEmpty()) {
|
||||||
|
return LevelRevisionInfo.DUMMY_LEVEL.getRelease();
|
||||||
|
}
|
||||||
|
|
||||||
|
int lastIndex = levelInfos.size() - 1;
|
||||||
|
LevelRevisionInfo outerLevel = levelInfos.get(lastIndex);
|
||||||
|
return outerLevel.getRelease();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Revision info [build date: "
|
||||||
|
+ new SimpleDateFormat().format(new Date(buildDate))
|
||||||
|
+ ", level info: " + levelInfos + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof RevisionInfoBean)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
RevisionInfoBean that = (RevisionInfoBean) obj;
|
||||||
|
return (this.buildDate == that.buildDate)
|
||||||
|
&& this.levelInfos.equals(that.levelInfos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return new Long(buildDate).hashCode() ^ levelInfos.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// helper class
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Revision info about one level of the application -- e.g. vitro, vivo,
|
||||||
|
* vivoCornell, etc.
|
||||||
|
*/
|
||||||
|
public static class LevelRevisionInfo {
|
||||||
|
/** A level to use when no actual level can be found. */
|
||||||
|
static final LevelRevisionInfo DUMMY_LEVEL = new LevelRevisionInfo(
|
||||||
|
"no name", "unknown", "unknown");
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final String release;
|
||||||
|
private final String revision;
|
||||||
|
|
||||||
|
LevelRevisionInfo(String name, String release, String revision) {
|
||||||
|
this.name = name;
|
||||||
|
this.release = release;
|
||||||
|
this.revision = revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRelease() {
|
||||||
|
return release;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRevision() {
|
||||||
|
return revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "[" + name + ", " + release + ", " + revision + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (obj == this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(obj instanceof LevelRevisionInfo)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LevelRevisionInfo that = (LevelRevisionInfo) obj;
|
||||||
|
return this.name.equals(that.name)
|
||||||
|
&& this.release.equals(that.release)
|
||||||
|
&& this.revision.equals(that.revision);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return name.hashCode() ^ release.hashCode() ^ revision.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,177 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.config;
|
||||||
|
|
||||||
|
import static edu.cornell.mannlib.vitro.webapp.config.RevisionInfoBean.DUMMY_BEAN;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.ServletContextEvent;
|
||||||
|
import javax.servlet.ServletContextListener;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.config.RevisionInfoBean.LevelRevisionInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
* Read the revision information, and store it in the servlet context.
|
||||||
|
*
|
||||||
|
* - The revision information is in a file in the classpath.
|
||||||
|
* - The name of the file is in RESOURCE_PATH, below.
|
||||||
|
* - The first line is the build date, with a format as in DATE_FORMAT, below.
|
||||||
|
* - Each additional non-blank line holds revision info for one application level:
|
||||||
|
* - level info is from inner (vitro) to outer (top-level product).
|
||||||
|
* - level info appears as product name, release name and revision level,
|
||||||
|
* delimited by " ~ ".
|
||||||
|
* - additional white space before and after info values is ignored.
|
||||||
|
*
|
||||||
|
* Example file:
|
||||||
|
* 2010-11-14 23:58:00
|
||||||
|
* vitroCore ~ Release 1.1 ~ 6604
|
||||||
|
* nihvivo ~ Release 1.1 ~ 1116
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
public class RevisionInfoSetup implements ServletContextListener {
|
||||||
|
private static final Log log = LogFactory.getLog(RevisionInfoSetup.class);
|
||||||
|
|
||||||
|
private static final Pattern LEVEL_INFO_PATTERN = Pattern
|
||||||
|
.compile("(.+) ~ (.+) ~ (.+)");
|
||||||
|
|
||||||
|
static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
|
||||||
|
static final String RESOURCE_PATH = "/WEB-INF/resources/revisionInfo.txt";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* On startup, read the revision info from the resource file in the
|
||||||
|
* classpath.
|
||||||
|
*
|
||||||
|
* If we can't find the file, or can't parse it, store an empty bean.
|
||||||
|
*
|
||||||
|
* Don't allow any Exceptions to percolate up past this point.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void contextInitialized(ServletContextEvent sce) {
|
||||||
|
ServletContext context = sce.getServletContext();
|
||||||
|
RevisionInfoBean bean;
|
||||||
|
try {
|
||||||
|
List<String> lines = readRevisionInfo(context);
|
||||||
|
bean = parseRevisionInformation(lines);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error(e, e);
|
||||||
|
bean = DUMMY_BEAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
RevisionInfoBean.setBean(sce.getServletContext(), bean);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> readRevisionInfo(ServletContext context)
|
||||||
|
throws IOException {
|
||||||
|
BufferedReader reader = null;
|
||||||
|
try {
|
||||||
|
reader = openRevisionInfoReader(context);
|
||||||
|
return readSignificantLines(reader);
|
||||||
|
} finally {
|
||||||
|
closeReader(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BufferedReader openRevisionInfoReader(ServletContext context)
|
||||||
|
throws FileNotFoundException {
|
||||||
|
InputStream stream = context.getResourceAsStream(RESOURCE_PATH);
|
||||||
|
if (stream == null) {
|
||||||
|
throw new FileNotFoundException(
|
||||||
|
"Can't find a resource in the webapp at '" + RESOURCE_PATH
|
||||||
|
+ "'.");
|
||||||
|
} else {
|
||||||
|
return new BufferedReader(new InputStreamReader(stream));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> readSignificantLines(BufferedReader reader)
|
||||||
|
throws IOException {
|
||||||
|
List<String> lines = new ArrayList<String>();
|
||||||
|
|
||||||
|
String line = null;
|
||||||
|
while (null != (line = reader.readLine())) {
|
||||||
|
line = line.trim();
|
||||||
|
if ((!line.isEmpty()) && (!line.startsWith("#"))) {
|
||||||
|
lines.add(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void closeReader(Reader reader) {
|
||||||
|
if (reader != null) {
|
||||||
|
try {
|
||||||
|
reader.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private RevisionInfoBean parseRevisionInformation(List<String> lines)
|
||||||
|
throws ParseException {
|
||||||
|
checkValidNumberOfLines(lines);
|
||||||
|
String dateLine = lines.get(0);
|
||||||
|
List<String> levelLines = lines.subList(1, lines.size());
|
||||||
|
|
||||||
|
Date buildDate = parseDateLine(dateLine);
|
||||||
|
List<LevelRevisionInfo> levelInfos = parseLevelLines(levelLines);
|
||||||
|
return new RevisionInfoBean(buildDate, levelInfos);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkValidNumberOfLines(List<String> lines)
|
||||||
|
throws ParseException {
|
||||||
|
if (lines.isEmpty()) {
|
||||||
|
throw new ParseException(
|
||||||
|
"The revision info resource file contains no data.", 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Date parseDateLine(String dateLine) throws ParseException {
|
||||||
|
return new SimpleDateFormat(DATE_FORMAT).parse(dateLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<LevelRevisionInfo> parseLevelLines(List<String> levelLines)
|
||||||
|
throws ParseException {
|
||||||
|
List<LevelRevisionInfo> infos = new ArrayList<LevelRevisionInfo>();
|
||||||
|
for (String line : levelLines) {
|
||||||
|
Matcher m = LEVEL_INFO_PATTERN.matcher(line);
|
||||||
|
if (m.matches()) {
|
||||||
|
String name = m.group(1).trim();
|
||||||
|
String release = m.group(2).trim();
|
||||||
|
String revision = m.group(3).trim();
|
||||||
|
infos.add(new LevelRevisionInfo(name, release, revision));
|
||||||
|
} else {
|
||||||
|
throw new ParseException(
|
||||||
|
"Failed to parse the revision info in '" + line + "'",
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return infos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** On shutdown, clean up. */
|
||||||
|
@Override
|
||||||
|
public void contextDestroyed(ServletContextEvent sce) {
|
||||||
|
RevisionInfoBean.removeBean(sce.getServletContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.config;
|
||||||
|
|
||||||
|
import static edu.cornell.mannlib.vitro.webapp.config.RevisionInfoBean.DUMMY_BEAN;
|
||||||
|
import static edu.cornell.mannlib.vitro.webapp.config.RevisionInfoBean.LevelRevisionInfo.DUMMY_LEVEL;
|
||||||
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.apache.log4j.Level;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import stubs.javax.servlet.ServletContextStub;
|
||||||
|
import stubs.javax.servlet.http.HttpSessionStub;
|
||||||
|
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.config.RevisionInfoBean.LevelRevisionInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for RevisionInfoBean
|
||||||
|
*/
|
||||||
|
public class RevisionInfoBeanTest extends AbstractTestClass {
|
||||||
|
private static final Date SAMPLE_DATE = new Date();
|
||||||
|
|
||||||
|
private static final LevelRevisionInfo LEVEL_1_INFO = new LevelRevisionInfo(
|
||||||
|
"level1name", "level1release", "level1revision");
|
||||||
|
private static final LevelRevisionInfo LEVEL_2_INFO = new LevelRevisionInfo(
|
||||||
|
"level2name", "level2release", "level2revision");
|
||||||
|
private static final LevelRevisionInfo LEVEL_3_INFO = new LevelRevisionInfo(
|
||||||
|
"level3name", "level3release", "level3revision");
|
||||||
|
|
||||||
|
private static final RevisionInfoBean BEAN_NO_LEVEL = buildBean(SAMPLE_DATE);
|
||||||
|
private static final RevisionInfoBean BEAN_1_LEVEL = buildBean(SAMPLE_DATE,
|
||||||
|
LEVEL_1_INFO);
|
||||||
|
private static final RevisionInfoBean BEAN_MULTI_LEVEL = buildBean(
|
||||||
|
SAMPLE_DATE, LEVEL_1_INFO, LEVEL_2_INFO, LEVEL_3_INFO);
|
||||||
|
|
||||||
|
private static RevisionInfoBean buildBean(Date date,
|
||||||
|
LevelRevisionInfo... levels) {
|
||||||
|
return new RevisionInfoBean(date, Arrays.asList(levels));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ServletContextStub context;
|
||||||
|
private HttpSessionStub session;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setupContext() {
|
||||||
|
context = new ServletContextStub();
|
||||||
|
session = new HttpSessionStub();
|
||||||
|
session.setServletContext(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void suppressInfoMessages() {
|
||||||
|
setLoggerLevel(RevisionInfoBean.class, Level.WARN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setBeanNormal() {
|
||||||
|
RevisionInfoBean.setBean(context, BEAN_1_LEVEL);
|
||||||
|
assertEquals("stored bean", BEAN_1_LEVEL,
|
||||||
|
RevisionInfoBean.getBean(session));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void setBeanNull() {
|
||||||
|
RevisionInfoBean.setBean(context, null);
|
||||||
|
assertEquals("dummy bean", DUMMY_BEAN,
|
||||||
|
RevisionInfoBean.getBean(session));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getBeanNoSession() {
|
||||||
|
setLoggerLevel(RevisionInfoBean.class, Level.ERROR);
|
||||||
|
|
||||||
|
assertEquals("noBean", DUMMY_BEAN, RevisionInfoBean.getBean(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getBeanNoAttribute() {
|
||||||
|
setLoggerLevel(RevisionInfoBean.class, Level.ERROR);
|
||||||
|
|
||||||
|
assertEquals("noAttribute", DUMMY_BEAN,
|
||||||
|
RevisionInfoBean.getBean(session));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getBeanAttributeIsWrongClass() {
|
||||||
|
setLoggerLevel(RevisionInfoBean.class, Level.OFF);
|
||||||
|
|
||||||
|
context.setAttribute(RevisionInfoBean.ATTRIBUTE_NAME, "A string!");
|
||||||
|
assertEquals("noAttribute", DUMMY_BEAN,
|
||||||
|
RevisionInfoBean.getBean(session));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void removeBean() {
|
||||||
|
RevisionInfoBean.setBean(context, BEAN_1_LEVEL);
|
||||||
|
assertEquals("stored bean", BEAN_1_LEVEL,
|
||||||
|
RevisionInfoBean.getBean(session));
|
||||||
|
|
||||||
|
setLoggerLevel(RevisionInfoBean.class, Level.ERROR);
|
||||||
|
|
||||||
|
RevisionInfoBean.removeBean(context);
|
||||||
|
assertEquals("dummy bean", DUMMY_BEAN,
|
||||||
|
RevisionInfoBean.getBean(session));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getReleaseLabelOneLevel() {
|
||||||
|
RevisionInfoBean.setBean(context, BEAN_1_LEVEL);
|
||||||
|
assertEquals("1 level release", LEVEL_1_INFO.getRelease(),
|
||||||
|
RevisionInfoBean.getBean(session).getReleaseLabel());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getReleaseLabelManyLevels() {
|
||||||
|
RevisionInfoBean.setBean(context, BEAN_MULTI_LEVEL);
|
||||||
|
assertEquals("many level release", LEVEL_3_INFO.getRelease(),
|
||||||
|
RevisionInfoBean.getBean(session).getReleaseLabel());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getReleaseLabelNoLevels() {
|
||||||
|
RevisionInfoBean.setBean(context, BEAN_NO_LEVEL);
|
||||||
|
assertEquals("0 level release", DUMMY_LEVEL.getRelease(),
|
||||||
|
RevisionInfoBean.getBean(session).getReleaseLabel());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getReleaseLabelNoBean() {
|
||||||
|
setLoggerLevel(RevisionInfoBean.class, Level.ERROR);
|
||||||
|
|
||||||
|
assertEquals("no bean release", DUMMY_LEVEL.getRelease(),
|
||||||
|
RevisionInfoBean.getBean(session).getReleaseLabel());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,183 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.config;
|
||||||
|
|
||||||
|
import static edu.cornell.mannlib.vitro.webapp.config.RevisionInfoBean.DUMMY_BEAN;
|
||||||
|
import static edu.cornell.mannlib.vitro.webapp.config.RevisionInfoSetup.DATE_FORMAT;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContextEvent;
|
||||||
|
import javax.servlet.ServletContextListener;
|
||||||
|
|
||||||
|
import org.apache.log4j.Level;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import stubs.javax.servlet.ServletContextStub;
|
||||||
|
import stubs.javax.servlet.http.HttpSessionStub;
|
||||||
|
|
||||||
|
import com.ibm.icu.text.SimpleDateFormat;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.testing.AbstractTestClass;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.config.RevisionInfoBean.LevelRevisionInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for RevisionInfoSetup
|
||||||
|
*/
|
||||||
|
public class RevisionInfoSetupTest extends AbstractTestClass {
|
||||||
|
private ServletContextStub context;
|
||||||
|
private HttpSessionStub session;
|
||||||
|
private ServletContextListener listener;
|
||||||
|
private ServletContextEvent event;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setupContext() {
|
||||||
|
context = new ServletContextStub();
|
||||||
|
|
||||||
|
session = new HttpSessionStub();
|
||||||
|
session.setServletContext(context);
|
||||||
|
|
||||||
|
event = new ServletContextEvent(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void createContextListener() {
|
||||||
|
listener = new RevisionInfoSetup();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void suppressInfoMessages() {
|
||||||
|
setLoggerLevel(RevisionInfoBean.class, Level.WARN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void noResourceFile() {
|
||||||
|
setLoggerLevel(RevisionInfoSetup.class, Level.OFF);
|
||||||
|
testThisExpectedFailure("no resource", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void resourceFileIsEmpty() {
|
||||||
|
setLoggerLevel(RevisionInfoSetup.class, Level.OFF);
|
||||||
|
testThisExpectedFailure("empty resource", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void resourceFileHasNoSignificantLines() {
|
||||||
|
setLoggerLevel(RevisionInfoSetup.class, Level.OFF);
|
||||||
|
testThisExpectedFailure("no siginificant lines", " \n # \n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void resourceFileHasInvalidDateLine() {
|
||||||
|
setLoggerLevel(RevisionInfoSetup.class, Level.OFF);
|
||||||
|
testThisExpectedFailure("invalid date line", "BOGUS DATE LINE\n"
|
||||||
|
+ "name ~ release ~ revision");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void resourceFileHasInvalidLevelLine() {
|
||||||
|
setLoggerLevel(RevisionInfoSetup.class, Level.OFF);
|
||||||
|
testThisExpectedFailure("invalid level line", "2010-10-13 23:55:00\n"
|
||||||
|
+ "name ~ release ~revision");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void simpleSingleLevel() {
|
||||||
|
testThisResourceFile(
|
||||||
|
"simple single level",
|
||||||
|
"2010-10-13 23:55:00\n" + "name ~ release ~ revision",
|
||||||
|
bean(date("2010-10-13 23:55:00"),
|
||||||
|
level("name", "release", "revision")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ignoreWhiteSpaceAroundDate() {
|
||||||
|
testThisResourceFile(
|
||||||
|
"white space around date",
|
||||||
|
" 1999-01-01 00:00:00 \n" + "name ~ release ~ revision",
|
||||||
|
bean(date("1999-01-01 00:00:00"),
|
||||||
|
level("name", "release", "revision")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ignoreWhiteSpaceInLevelInfo() {
|
||||||
|
testThisResourceFile(
|
||||||
|
"white space in level info",
|
||||||
|
"2010-10-13 23:55:00\n"
|
||||||
|
+ " name ~ release ~ revision ",
|
||||||
|
bean(date("2010-10-13 23:55:00"),
|
||||||
|
level("name", "release", "revision")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void ignoreBlankLinesAndComments() {
|
||||||
|
testThisResourceFile(
|
||||||
|
"ignore empty lines",
|
||||||
|
"2010-10-13 23:55:00\n" + "\n" + " \n" + " # \n"
|
||||||
|
+ "name ~ release ~ revision",
|
||||||
|
bean(date("2010-10-13 23:55:00"),
|
||||||
|
level("name", "release", "revision")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseMultipleLevels() {
|
||||||
|
testThisResourceFile(
|
||||||
|
"multiple levels",
|
||||||
|
"2010-10-13 23:55:00\n" + "name ~ release ~ revision\n"
|
||||||
|
+ "name2 ~ release2 ~ revision2\n",
|
||||||
|
bean(date("2010-10-13 23:55:00"),
|
||||||
|
level("name", "release", "revision"),
|
||||||
|
level("name2", "release2", "revision2")));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseNoLevels() {
|
||||||
|
testThisResourceFile("no levels", "2010-10-13 23:55:00\n",
|
||||||
|
bean(date("2010-10-13 23:55:00")));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// helper methods
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
private RevisionInfoBean bean(Date date, LevelRevisionInfo... levels) {
|
||||||
|
return new RevisionInfoBean(date, Arrays.asList(levels));
|
||||||
|
}
|
||||||
|
|
||||||
|
private LevelRevisionInfo level(String name, String release, String revision) {
|
||||||
|
return new LevelRevisionInfo(name, release, revision);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Date date(String string) {
|
||||||
|
try {
|
||||||
|
return new SimpleDateFormat(DATE_FORMAT).parse(string);
|
||||||
|
} catch (ParseException e) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Can't parse this date string: '" + string + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test these file contents, compare to this expected bean.
|
||||||
|
*/
|
||||||
|
private void testThisResourceFile(String message, String fileContents,
|
||||||
|
RevisionInfoBean expected) {
|
||||||
|
context.setMockResource(RevisionInfoSetup.RESOURCE_PATH, fileContents);
|
||||||
|
|
||||||
|
listener.contextInitialized(event);
|
||||||
|
assertEquals(message, expected, RevisionInfoBean.getBean(session));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test these file contents, expect the dummy bean as a result.
|
||||||
|
*/
|
||||||
|
private void testThisExpectedFailure(String message, String fileContents) {
|
||||||
|
testThisResourceFile(message, fileContents, DUMMY_BEAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
package stubs.javax.servlet;
|
package stubs.javax.servlet;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
@ -19,7 +20,6 @@ import javax.servlet.ServletException;
|
||||||
/**
|
/**
|
||||||
* A simple stand-in for the {@link ServletContext}, for use in unit tests.
|
* A simple stand-in for the {@link ServletContext}, for use in unit tests.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public class ServletContextStub implements ServletContext {
|
public class ServletContextStub implements ServletContext {
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
@ -27,6 +27,18 @@ public class ServletContextStub implements ServletContext {
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
private final Map<String, Object> attributes = new HashMap<String, Object>();
|
private final Map<String, Object> attributes = new HashMap<String, Object>();
|
||||||
|
private final Map<String, String> mockResources = new HashMap<String, String>();
|
||||||
|
|
||||||
|
public void setMockResource(String path, String contents) {
|
||||||
|
if (path == null) {
|
||||||
|
throw new NullPointerException("path may not be null.");
|
||||||
|
}
|
||||||
|
if (contents == null) {
|
||||||
|
mockResources.remove(path);
|
||||||
|
} else {
|
||||||
|
mockResources.put(path, contents);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// Stub methods
|
// Stub methods
|
||||||
|
@ -56,6 +68,15 @@ public class ServletContextStub implements ServletContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getResourceAsStream(String path) {
|
||||||
|
if (mockResources.containsKey(path)) {
|
||||||
|
return new ByteArrayInputStream(mockResources.get(path).getBytes());
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
// Un-implemented methods
|
// Un-implemented methods
|
||||||
// ----------------------------------------------------------------------
|
// ----------------------------------------------------------------------
|
||||||
|
@ -79,7 +100,7 @@ public class ServletContextStub implements ServletContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("rawtypes")
|
||||||
public Enumeration getInitParameterNames() {
|
public Enumeration getInitParameterNames() {
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
"ServletContextStub.getInitParameterNames() not implemented.");
|
"ServletContextStub.getInitParameterNames() not implemented.");
|
||||||
|
@ -128,13 +149,7 @@ public class ServletContextStub implements ServletContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream getResourceAsStream(String arg0) {
|
@SuppressWarnings("rawtypes")
|
||||||
throw new RuntimeException(
|
|
||||||
"ServletContextStub.getResourceAsStream() not implemented.");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public Set getResourcePaths(String arg0) {
|
public Set getResourcePaths(String arg0) {
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
"ServletContextStub.getResourcePaths() not implemented.");
|
"ServletContextStub.getResourcePaths() not implemented.");
|
||||||
|
@ -159,14 +174,14 @@ public class ServletContextStub implements ServletContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("rawtypes")
|
||||||
public Enumeration getServletNames() {
|
public Enumeration getServletNames() {
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
"ServletContextStub.getServletNames() not implemented.");
|
"ServletContextStub.getServletNames() not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("rawtypes")
|
||||||
public Enumeration getServlets() {
|
public Enumeration getServlets() {
|
||||||
throw new RuntimeException(
|
throw new RuntimeException(
|
||||||
"ServletContextStub.getServlets() not implemented.");
|
"ServletContextStub.getServlets() not implemented.");
|
||||||
|
|
132
webapp/test/stubs/javax/servlet/http/HttpSessionStub.java
Normal file
132
webapp/test/stubs/javax/servlet/http/HttpSessionStub.java
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package stubs.javax.servlet.http;
|
||||||
|
|
||||||
|
import java.util.Enumeration;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple stand-in for the HttpSession, for use in unit tests.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public class HttpSessionStub implements HttpSession {
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Stub infrastructure
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
private ServletContext context;
|
||||||
|
|
||||||
|
public void setServletContext(ServletContext context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Stub methods
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ServletContext getServletContext() {
|
||||||
|
return this.context;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Un-implemented methods
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getAttribute(String arg0) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"HttpSessionStub.getAttribute() not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
public Enumeration getAttributeNames() {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"HttpSessionStub.getAttributeNames() not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getCreationTime() {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"HttpSessionStub.getCreationTime() not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
throw new RuntimeException("HttpSessionStub.getId() not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLastAccessedTime() {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"HttpSessionStub.getLastAccessedTime() not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxInactiveInterval() {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"HttpSessionStub.getMaxInactiveInterval() not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public javax.servlet.http.HttpSessionContext getSessionContext() {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"HttpSessionStub.getSessionContext() not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getValue(String arg0) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"HttpSessionStub.getValue() not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getValueNames() {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"HttpSessionStub.getValueNames() not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invalidate() {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"HttpSessionStub.invalidate() not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNew() {
|
||||||
|
throw new RuntimeException("HttpSessionStub.isNew() not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putValue(String arg0, Object arg1) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"HttpSessionStub.putValue() not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeAttribute(String arg0) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"HttpSessionStub.removeAttribute() not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeValue(String arg0) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"HttpSessionStub.removeValue() not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAttribute(String arg0, Object arg1) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"HttpSessionStub.setAttribute() not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMaxInactiveInterval(int arg0) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"HttpSessionStub.setMaxInactiveInterval() not implemented.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue