diff --git a/code/pom.xml b/code/pom.xml
index 884ef26..d61bb09 100644
--- a/code/pom.xml
+++ b/code/pom.xml
@@ -227,7 +227,7 @@
org.jetbrains
annotations
- 22.0.0
+ 24.0.1
junit
diff --git a/code/src/main/java/org/nocturne/caption/CaptionsImpl.java b/code/src/main/java/org/nocturne/caption/CaptionsImpl.java
index 5e6f0a9..daa8d28 100644
--- a/code/src/main/java/org/nocturne/caption/CaptionsImpl.java
+++ b/code/src/main/java/org/nocturne/caption/CaptionsImpl.java
@@ -4,6 +4,7 @@
package org.nocturne.caption;
import com.google.inject.Singleton;
+import org.apache.log4j.Logger;
import org.nocturne.exception.ConfigurationException;
import org.nocturne.main.ApplicationContext;
@@ -31,6 +32,8 @@
*/
@Singleton
public class CaptionsImpl implements Captions {
+ private static final Logger logger = Logger.getLogger(CaptionsImpl.class);
+
private static final Pattern CAPTIONS_FILE_PATTERN = Pattern.compile("captions_[\\w]{2}\\.properties");
/**
@@ -135,6 +138,7 @@ private static void save(Properties properties, String language) {
properties.store(writer, null);
writer.close();
} catch (IOException e) {
+ logger.error("Can't write into file " + file + '.', e);
throw new ConfigurationException("Can't write into file " + file + '.', e);
}
}
@@ -166,6 +170,7 @@ private void loadPropertiesForProduction() {
reader.close();
propertiesMap.put(language, properties);
} catch (IOException e) {
+ logger.error("Can't load caption properties for language " + language + '.', e);
throw new ConfigurationException("Can't load caption properties for language " + language + '.', e);
}
}
diff --git a/code/src/main/java/org/nocturne/link/Links.java b/code/src/main/java/org/nocturne/link/Links.java
index ed8c573..be9c133 100644
--- a/code/src/main/java/org/nocturne/link/Links.java
+++ b/code/src/main/java/org/nocturne/link/Links.java
@@ -43,6 +43,8 @@
* @author Mike Mirzayanov
*/
public class Links {
+ private static final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(Links.class);
+
private static final Lock addLinkLock = new ReentrantLock();
private static final int INTERCEPTOR_MAX_PERMIT_COUNT = 8 * Runtime.getRuntime().availableProcessors();
@@ -107,6 +109,8 @@ public static String getLinkName(@Nonnull Class extends Page> pageClass) {
}
if (clazz == null) {
+ logger.error("Page class should have @Link or @LinkSet annotation, but "
+ + pageClass.getName() + " hasn't.");
throw new NocturneException("Page class should have @Link or @LinkSet annotation, but "
+ pageClass.getName() + " hasn't.");
}
@@ -131,6 +135,7 @@ public static void add(Class extends Page> clazz, List linkSet) {
try {
String name = getLinkName(clazz);
if (classesByName.containsKey(name) && !clazz.equals(classesByName.get(name))) {
+ logger.error("Can't add page which is not unique by it's name: " + clazz.getName() + '.');
throw new ConfigurationException("Can't add page which is not unique by it's name: "
+ clazz.getName() + '.');
}
@@ -151,10 +156,12 @@ public static void add(Class extends Page> clazz, List linkSet) {
for (Map linkMap : linksByPage.values()) {
if (linkMap.containsKey(pageLink)) {
+ logger.error("Page link \"" + pageLink + "\" already registered.");
throw new ConfigurationException("Page link \"" + pageLink + "\" already registered.");
}
}
if (links.containsKey(pageLink)) {
+ logger.error("Page link \"" + pageLink + "\" already registered.");
throw new ConfigurationException("Page link \"" + pageLink + "\" already registered.");
}
@@ -176,6 +183,7 @@ public static void add(Class extends Page> clazz, List linkSet) {
public static void add(Class extends Page> clazz) {
List linkSet = getLinksViaReflection(clazz);
if (linkSet.isEmpty()) {
+ logger.error("Can't find link for page " + clazz.getName() + '.');
throw new ConfigurationException("Can't find link for page " + clazz.getName() + '.');
}
@@ -227,11 +235,12 @@ public static String getLinkByMap(Class extends Page> clazz, @Nullable String
if (bestMatchedLinkSections == null) {
if (linkName == null || linkName.isEmpty()) {
+ logger.error("Can't find link for page " + clazz.getName() + '.');
throw new NoSuchLinkException("Can't find link for page " + clazz.getName() + '.');
} else {
- throw new NoSuchLinkException(
- "Can't find link with name \'" + linkName + "\' for page " + clazz.getName() + '.'
- );
+ logger.error("Can't find link with name '" + linkName + "' for page " + clazz.getName() + '.');
+ throw new NoSuchLinkException("Can't find link with name '"
+ + linkName + "' for page " + clazz.getName() + '.');
}
}
@@ -292,6 +301,7 @@ public static String getLinkByMap(Class extends Page> clazz, @Nullable String
for (String skipInterceptor : bestMatchedLink.skipInterceptors()) {
if (skipInterceptor.equals(e.getKey())) {
skip = true;
+ break;
}
}
if (!skip) {
@@ -360,6 +370,7 @@ private static List toStringList(@Nonnull TemplateSequenceModel sequence
try {
item = sequence.get(i);
} catch (TemplateModelException e) {
+ logger.error("Can't get item of Freemarker sequence.", e);
throw new NocturneException("Can't get item of Freemarker sequence.", e);
}
@@ -387,6 +398,7 @@ private static int getSize(@Nonnull TemplateSequenceModel sequence) {
try {
return sequence.size();
} catch (TemplateModelException e) {
+ logger.error("Can't get size of Freemarker sequence.", e);
throw new NocturneException("Can't get size of Freemarker sequence.", e);
}
}
@@ -416,6 +428,7 @@ public static String getLinkByMap(String name, @Nullable String linkName, Map clazz = classesByName.get(name);
if (clazz == null) {
+ logger.error("Can't find link for page " + name + '.');
throw new NoSuchLinkException("Can't find link for page " + name + '.');
} else {
return getLinkByMap(clazz, linkName, params);
@@ -462,6 +475,7 @@ private static Map convertArrayToMap(Object... params) {
}
if (paramCount % 2 != 0) {
+ logger.error("Params should contain even number of elements.");
throw new IllegalArgumentException("Params should contain even number of elements.");
}
@@ -480,7 +494,7 @@ private static Map convertArrayToMap(Object... params) {
* @throws NoSuchLinkException if no such link exists
*/
public static String getLink(Class extends Page> pageClass) {
- return getLinkByMap(pageClass, null, Collections.emptyMap());
+ return getLinkByMap(pageClass, null, Collections.emptyMap());
}
/**
@@ -524,6 +538,7 @@ public static LinkMatchResult match(String link) {
}
if (!link.startsWith("/")) {
+ logger.error("Link \"" + link + "\" doesn't start with '/'.");
throw new IllegalArgumentException("Link \"" + link + "\" doesn't start with '/'.");
}
@@ -559,6 +574,7 @@ public static LinkMatchResult match(String link) {
private static Map match(String[] linkTokens, String linkText) {
List sections = sectionsByLinkText.get(linkText);
if (sections == null) {
+ logger.error("Can't find sections for linkText=\"" + linkText + "\".");
throw new NocturneException("Can't find sections for linkText=\"" + linkText + "\".");
}
@@ -603,6 +619,8 @@ public NoSuchLinkException(String message) {
private static List parseLinkToLinkSections(String linkText) {
if (linkText == null || linkText.startsWith("/") || linkText.endsWith("/")) {
+ logger.error("Page link has illegal format, use links like 'home', 'page/{index}', " +
+ "'page/{index(long,positive):1,2,3}', 'section/{name(string,!blank):!a,b,c}'.");
throw new ConfigurationException("Page link has illegal format, use links like 'home', 'page/{index}', " +
"'page/{index(long,positive):1,2,3}', 'section/{name(string,!blank):!a,b,c}'."
);
@@ -755,6 +773,7 @@ public boolean isSuitable(String value) {
private void ensureValueSection(String fieldName) {
if (parameter) {
+ logger.error("Can't read field '" + fieldName + "' of non-value section '" + section + "'.");
throw new IllegalStateException(String.format(
"Can't read field '%s' of non-value section '%s'.", fieldName, section
));
@@ -763,6 +782,7 @@ private void ensureValueSection(String fieldName) {
private void ensureParameterSection(String fieldName) {
if (!parameter) {
+ logger.error("Can't read field '" + fieldName + "' of non-parameter section '" + section + "'.");
throw new IllegalStateException(String.format(
"Can't read field '%s' of non-parameter section '%s'.", fieldName, section
));
@@ -988,6 +1008,8 @@ public boolean isSuitable(String value) {
}
};
} else {
+ logger.error("Link section '" + section + "' contains unsupported parameter restriction '"
+ + restrictionRule + "'.");
throw new ConfigurationException(String.format(
"Link section '%s' contains unsupported parameter restriction '%s'.",
section, restrictionRule
@@ -1006,13 +1028,15 @@ public static void addInterceptor(String name, Interceptor interceptor) {
ensureInterceptorName(name);
if (interceptor == null) {
- throw new IllegalArgumentException("Argument \'interceptor\' is \'null\'.");
+ logger.error("Argument 'interceptor' is 'null'.");
+ throw new IllegalArgumentException("Argument 'interceptor' is 'null'.");
}
interceptorSemaphore.acquireUninterruptibly(INTERCEPTOR_MAX_PERMIT_COUNT);
try {
if (interceptorByNameMap.containsKey(name)) {
- throw new IllegalStateException("Interceptor with name \'" + name + "\' already added.");
+ logger.error("Interceptor with name '" + name + "' already added.");
+ throw new IllegalStateException("Interceptor with name '" + name + "' already added.");
}
interceptorByNameMap.put(name, interceptor);
} finally {
@@ -1055,7 +1079,8 @@ public static boolean hasInterceptor(String name) {
private static void ensureInterceptorName(String name) {
if (name == null || name.isEmpty()) {
- throw new IllegalArgumentException("Argument \'name\' is \'null\' or empty.");
+ logger.error("Argument 'name' is 'null' or empty.");
+ throw new IllegalArgumentException("Argument 'name' is 'null' or empty.");
}
}
diff --git a/code/src/main/java/org/nocturne/main/ActionMap.java b/code/src/main/java/org/nocturne/main/ActionMap.java
index e6abefb..448552e 100644
--- a/code/src/main/java/org/nocturne/main/ActionMap.java
+++ b/code/src/main/java/org/nocturne/main/ActionMap.java
@@ -24,6 +24,8 @@
* @author Mike Mirzayanov
*/
class ActionMap {
+ private static final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(ActionMap.class);
+
/* Default action has empty key "". */
private final Map actions = new ConcurrentHashMap<>();
@@ -55,6 +57,8 @@ class ActionMap {
private void processMethodAsDefault(FastClass clazz, Method method) {
if (!actions.containsKey("") && "action".equals(method.getName()) && method.getParameterTypes().length == 0) {
if (method.getReturnType() != void.class) {
+ logger.error("Default action method [name=" + method.getName() + ", " +
+ "class=" + clazz.getName() + "] should return void.");
throw new ConfigurationException("Default action method [name=" + method.getName() + ", " +
"class=" + clazz.getName() + "] should return void.");
}
@@ -63,6 +67,8 @@ private void processMethodAsDefault(FastClass clazz, Method method) {
if (!validators.containsKey("") && "validate".equals(method.getName()) && method.getParameterTypes().length == 0) {
if (method.getReturnType() != boolean.class) {
+ logger.error("Default validation method [name=" + method.getName() + ", " +
+ "class=" + clazz.getName() + "] should return boolean.");
throw new ConfigurationException("Default validation method [name=" + method.getName() + ", " +
"class=" + clazz.getName() + "] should return boolean.");
}
@@ -71,6 +77,8 @@ private void processMethodAsDefault(FastClass clazz, Method method) {
if (!invalids.containsKey("") && "invalid".equals(method.getName()) && method.getParameterTypes().length == 0) {
if (method.getReturnType() != void.class) {
+ logger.error("Default invalid method [name=" + method.getName() + ", " +
+ "class=" + clazz.getName() + "] should return void.");
throw new ConfigurationException("Default invalid method [name=" + method.getName() + ", " +
"class=" + clazz.getName() + "] should return void.");
}
@@ -80,6 +88,7 @@ private void processMethodAsDefault(FastClass clazz, Method method) {
private static void ensureProperlyAnnotatedParameters(Method method) {
if (method.getParameterTypes().length != method.getParameterAnnotations().length) {
+ logger.error("Expected \"method.getParameterTypes().length != method.getParameterAnnotations().length\".");
throw new NocturneException("Expected \"method.getParameterTypes().length != method.getParameterAnnotations().length\".");
}
@@ -94,10 +103,14 @@ private static void ensureProperlyAnnotatedParameters(Method method) {
}
}
if (!hasParameter) {
+ logger.error("Each parameter of the method " + method.getDeclaringClass().getName()
+ + '#' + method.getName() + " should be annotated with @Parameter.");
throw new ConfigurationException("Each parameter of the method " + method.getDeclaringClass().getName()
+ '#' + method.getName() + " should be annotated with @Parameter.");
}
if (!hasNamedParameter) {
+ logger.error("Each @Parameter in the method " + method.getDeclaringClass().getName()
+ + '#' + method.getName() + " should have name.");
throw new ConfigurationException("Each @Parameter in the method " + method.getDeclaringClass().getName()
+ '#' + method.getName() + " should have name.");
}
@@ -109,6 +122,8 @@ private void processMethod(FastClass clazz, Method method) {
if (action != null) {
if (actions.containsKey(action.value())) {
+ logger.error("There are two or more methods for " +
+ clazz.getName() + " marked with @Action[" + action.value() + "].");
throw new ConfigurationException("There are two or more methods for " +
clazz.getName() + " marked with @Action[" + action.value() + "].");
}
@@ -116,6 +131,8 @@ private void processMethod(FastClass clazz, Method method) {
ensureProperlyAnnotatedParameters(method);
if (method.getReturnType() != void.class) {
+ logger.error("Method with annotation @Action [name=" + method.getName() + ", " +
+ "class=" + clazz.getName() + "] should return void.");
throw new ConfigurationException("Method with annotation @Action [name=" + method.getName() + ", " +
"class=" + clazz.getName() + "] should return void.");
}
@@ -127,6 +144,8 @@ private void processMethod(FastClass clazz, Method method) {
if (validate != null) {
if (validators.containsKey(validate.value())) {
+ logger.error("There are two or more methods for " +
+ clazz.getName() + " marked with @Validate[" + validate.value() + "].");
throw new ConfigurationException("There are two or more methods for " +
clazz.getName() + " marked with @Validate[" + validate.value() + "].");
}
@@ -134,6 +153,8 @@ private void processMethod(FastClass clazz, Method method) {
ensureProperlyAnnotatedParameters(method);
if (method.getReturnType() != boolean.class) {
+ logger.error("Method with annotation @Validate [name=" + method.getName() + ", " +
+ "class=" + clazz.getName() + "] should return boolean.");
throw new ConfigurationException("Method with annotation @Validate [name=" + method.getName() + ", " +
"class=" + clazz.getName() + "] should return boolean.");
}
@@ -145,6 +166,8 @@ private void processMethod(FastClass clazz, Method method) {
if (invalid != null) {
if (invalids.containsKey(invalid.value())) {
+ logger.error("There are two or more methods for " +
+ clazz.getName() + " marked with @Invalid[" + invalid.value() + "].");
throw new ConfigurationException("There are two or more methods for " +
clazz.getName() + " marked with @Invalid[" + invalid.value() + "].");
}
@@ -152,6 +175,8 @@ private void processMethod(FastClass clazz, Method method) {
ensureProperlyAnnotatedParameters(method);
if (method.getReturnType() != void.class) {
+ logger.error("Method with annotation @Invalid [name=" + method.getName() + ", " +
+ "class=" + clazz.getName() + "] should return void.");
throw new ConfigurationException("Method with annotation @Invalid [name=" + method.getName() + ", " +
"class=" + clazz.getName() + "] should return void.");
}
diff --git a/code/src/main/java/org/nocturne/main/ApplicationContext.java b/code/src/main/java/org/nocturne/main/ApplicationContext.java
index f8a3600..6374a7a 100644
--- a/code/src/main/java/org/nocturne/main/ApplicationContext.java
+++ b/code/src/main/java/org/nocturne/main/ApplicationContext.java
@@ -47,6 +47,8 @@
*/
@SuppressWarnings({"WeakerAccess", "unused"})
public class ApplicationContext {
+ private static final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(ApplicationContext.class);
+
/**
* The only singleton instance.
*/
@@ -698,6 +700,7 @@ void setReloadingClassLoader(ClassLoader loader) {
*/
public void addReloadingClassPath(File dir) {
if (!dir.isDirectory()) {
+ logger.error("Path " + dir.getName() + " expected to be a directory.");
throw new ConfigurationException("Path " + dir.getName() + " expected to be a directory.");
}
reloadingClassPaths.add(dir);
@@ -707,6 +710,7 @@ public void addReloadingClassPath(File dir) {
try {
ReflectionUtil.invoke(context, "addReloadingClassPath", dir);
} catch (ReflectionException e) {
+ logger.error("Can't call addReloadingClassPath for ReloadingContext.", e);
throw new NocturneException("Can't call addReloadingClassPath for ReloadingContext.", e);
}
} else {
@@ -781,6 +785,7 @@ private void initializeCaptions() {
Class extends Captions> clazz = (Class extends Captions>) getClass().getClassLoader().loadClass(captionsImplClass);
captions = injector.getInstance(clazz);
} catch (ClassNotFoundException e) {
+ logger.error("Class " + captionsImplClass + " not found.", e);
throw new ConfigurationException("Class " + captionsImplClass + " should implement Captions.", e);
} finally {
lock.unlock();
@@ -905,6 +910,7 @@ private static final class RequestContext {
private RequestContext(@Nullable HttpServletRequest request, @Nullable HttpServletResponse response) {
if ((request == null) ^ (response == null)) {
+ logger.error("It is not possible case '(request == null) ^ (response == null)'.");
throw new IllegalArgumentException("It is not possible case '(request == null) ^ (response == null)'.");
}
diff --git a/code/src/main/java/org/nocturne/main/ApplicationContextLoader.java b/code/src/main/java/org/nocturne/main/ApplicationContextLoader.java
index 836a866..c36d9e4 100644
--- a/code/src/main/java/org/nocturne/main/ApplicationContextLoader.java
+++ b/code/src/main/java/org/nocturne/main/ApplicationContextLoader.java
@@ -124,6 +124,8 @@ private static void setupAllowedLanguages() {
for (String token : tokens) {
if (!token.isEmpty()) {
if (token.length() != 2) {
+ logger.error("nocturne.allowed-languages should contain the " +
+ "list of 2-letters language codes separated with comma.");
throw new ConfigurationException("nocturne.allowed-languages should contain the " +
"list of 2-letters language codes separated with comma.");
}
@@ -144,6 +146,8 @@ private static void setupCountryToLanguage() {
for (String token : tokens) {
if (!token.isEmpty()) {
if (!COUNTRIES_TO_LANGUAGE_PATTERN.matcher(token).matches()) {
+ logger.error("nocturne.countries-to-language should have a form like " +
+ "\"RU,BY:ru;EN,GB,US,CA:en\".");
throw new ConfigurationException("nocturne.countries-to-language should have a form like " +
"\"RU,BY:ru;EN,GB,US,CA:en\".");
}
@@ -182,6 +186,7 @@ private static void setupDebugCaptionsDir() {
String dir = properties.getProperty("nocturne.debug-captions-dir");
if (dir != null && !dir.isEmpty()) {
if (!new File(dir).isDirectory() && ApplicationContext.getInstance().isDebug()) {
+ logger.error("nocturne.debug-captions-dir property should be a directory.");
throw new ConfigurationException("nocturne.debug-captions-dir property should be a directory.");
}
ApplicationContext.getInstance().setDebugCaptionsDir(dir);
@@ -194,6 +199,7 @@ private static void setupDefaultLocale() {
String language = properties.getProperty("nocturne.default-language");
if (language != null && !language.isEmpty()) {
if (language.length() != 2) {
+ logger.error("Language is expected to have exactly two letters.");
throw new ConfigurationException("Language is expected to have exactly two letters.");
}
ApplicationContext.getInstance().setDefaultLocale(language);
@@ -205,10 +211,12 @@ private static void setupRequestRouter() {
if (properties.containsKey("nocturne.request-router")) {
String resolver = properties.getProperty("nocturne.request-router");
if (resolver == null || resolver.isEmpty()) {
+ logger.error("Parameter nocturne.request-router can't be empty.");
throw new ConfigurationException("Parameter nocturne.request-router can't be empty.");
}
ApplicationContext.getInstance().setRequestRouter(resolver);
} else {
+ logger.error("Missed parameter nocturne.request-router.");
throw new ConfigurationException("Missed parameter nocturne.request-router.");
}
}
@@ -255,6 +263,7 @@ private static void setupSkipRegex() {
try {
ApplicationContext.getInstance().setSkipRegex(Pattern.compile(regex));
} catch (PatternSyntaxException e) {
+ logger.error("Parameter nocturne.skip-regex contains invalid pattern.", e);
throw new ConfigurationException("Parameter nocturne.skip-regex contains invalid pattern.", e);
}
}
@@ -291,6 +300,8 @@ private static void setupReloadingClassPaths() {
if (dir != null && !dir.isEmpty()) {
File file = new File(dir);
if (!file.isDirectory() && ApplicationContext.getInstance().isDebug()) {
+ logger.error("Each item in nocturne.reloading-class-paths should be a directory,"
+ + " but " + file + " is not.");
throw new ConfigurationException("Each item in nocturne.reloading-class-paths should be a directory,"
+ " but " + file + " is not.");
}
@@ -307,10 +318,12 @@ private static void setupTemplates() {
try {
int templatesUpdateDelay = Integer.parseInt(properties.getProperty("nocturne.templates-update-delay"));
if (templatesUpdateDelay < 0 || templatesUpdateDelay > 86400) {
+ logger.error("Parameter nocturne.templates-update-delay should be non-negative integer not greater than 86400.");
throw new ConfigurationException("Parameter nocturne.templates-update-delay should be non-negative integer not greater than 86400.");
}
ApplicationContext.getInstance().setTemplatesUpdateDelay(templatesUpdateDelay);
} catch (NumberFormatException e) {
+ logger.error("Parameter nocturne.templates-update-delay should be integer.", e);
throw new ConfigurationException("Parameter nocturne.templates-update-delay should be integer.", e);
}
}
@@ -322,6 +335,7 @@ private static void setupTemplates() {
for (String templatePath : templatePaths) {
if (templatePath.isEmpty()) {
+ logger.error("Item of parameter nocturne.template-paths can't be empty.");
throw new ConfigurationException("Item of parameter nocturne.template-paths can't be empty.");
}
}
@@ -331,10 +345,12 @@ private static void setupTemplates() {
String templatesPath = StringUtils.trimToEmpty(properties.getProperty("nocturne.templates-path"));
if (templatesPath.isEmpty()) {
+ logger.error("Parameter nocturne.templates-path can't be empty.");
throw new ConfigurationException("Parameter nocturne.templates-path can't be empty.");
}
ApplicationContext.getInstance().setTemplatePaths(new String[]{templatesPath});
} else {
+ logger.error("Missing parameter nocturne.template-paths.");
throw new ConfigurationException("Missing parameter nocturne.template-paths.");
}
@@ -348,6 +364,7 @@ private static void setupTemplates() {
if (properties.containsKey("nocturne.use-component-templates")) {
String useComponentTemplates = properties.getProperty("nocturne.use-component-templates");
if (!"false".equals(useComponentTemplates) && !"true".equals(useComponentTemplates)) {
+ logger.error("Parameter nocturne.use-component-templates expected to be 'false' or 'true'.");
throw new ConfigurationException("Parameter nocturne.use-component-templates expected to be 'false' or 'true'.");
}
boolean use = "true".equals(useComponentTemplates);
@@ -360,6 +377,7 @@ private static void setupTemplates() {
if (componentTemplatesLessCommonsFile.isFile()) {
ApplicationContext.getInstance().setComponentTemplatesLessCommonsFile(componentTemplatesLessCommonsFile);
} else {
+ logger.error("Parameter nocturne.component-templates-less-commons-file is expected to be a file.");
throw new ConfigurationException("Parameter nocturne.component-templates-less-commons-file is expected to be a file.");
}
}
@@ -433,6 +451,7 @@ private static void setupInjector() {
try {
module.setModule(getApplicationModule(guiceModuleClassName));
} catch (Exception e) {
+ logger.error("Can't load application Guice module.", e);
throw new ConfigurationException("Can't load application Guice module.", e);
}
}
@@ -445,10 +464,13 @@ private static void setupInjector() {
method.setAccessible(true);
method.invoke(ApplicationContext.getInstance(), injector);
} catch (NoSuchMethodException e) {
+ logger.error("Can't find method setInjector.", e);
throw new NocturneException("Can't find method setInjector.", e);
} catch (InvocationTargetException e) {
+ logger.error("InvocationTargetException", e);
throw new NocturneException("InvocationTargetException", e);
} catch (IllegalAccessException e) {
+ logger.error("IllegalAccessException", e);
throw new NocturneException("IllegalAccessException", e);
}
} else {
@@ -509,9 +531,11 @@ private static void runModuleStartups() {
runnable = (Runnable) ApplicationContext.getInstance().getInjector().getInstance(
ApplicationContext.class.getClassLoader().loadClass(startupClassName));
} catch (ClassCastException e) {
+ logger.error("Startup class " + startupClassName + " must implement Runnable.", e);
throw new ModuleInitializationException("Startup class " + startupClassName
+ " must implement Runnable.", e);
} catch (ClassNotFoundException e) {
+ logger.error("Can't load startup class be name " + startupClassName + '.', e);
throw new ModuleInitializationException("Can't load startup class be name "
+ startupClassName + '.', e);
}
@@ -540,10 +564,10 @@ static void shutdown() {
}
static {
-
try (InputStream inputStream = ApplicationContextLoader.class.getResourceAsStream(Constants.CONFIGURATION_FILE)) {
properties.load(inputStream);
} catch (IOException e) {
+ logger.error("Can't load resource file " + Constants.CONFIGURATION_FILE + '.', e);
throw new ConfigurationException("Can't load resource file " + Constants.CONFIGURATION_FILE + '.', e);
}
}
diff --git a/code/src/main/java/org/nocturne/main/PageLoader.java b/code/src/main/java/org/nocturne/main/PageLoader.java
index 54a17c5..86ffa08 100644
--- a/code/src/main/java/org/nocturne/main/PageLoader.java
+++ b/code/src/main/java/org/nocturne/main/PageLoader.java
@@ -41,10 +41,12 @@ void initialize() {
ApplicationContext.getInstance().getRequestRouter()
).getConstructor().newInstance();
} catch (NoSuchMethodException e) {
+ logger.error(
+ "Application page class name resolver does not have default constructor.", e);
throw new ConfigurationException(
- "Application page class name resolver does not have default constructor.", e
- );
+ "Application page class name resolver does not have default constructor.", e);
} catch (Exception e) {
+ logger.error("Can't load application page class name resolver.", e);
throw new ConfigurationException("Can't load application page class name resolver.", e);
}
}
@@ -106,6 +108,7 @@ public Page loadPage(String pageClassName) {
Class pageClass = (Class) PageLoader.class.getClassLoader().loadClass(pageClassName);
return ApplicationContext.getInstance().getInjector().getInstance(pageClass);
} catch (Exception e) {
+ logger.error("Can't load page " + pageClassName + '.', e);
throw new ConfigurationException("Can't load page " + pageClassName + '.', e);
}
}
diff --git a/code/src/main/java/org/nocturne/main/ParametersInjector.java b/code/src/main/java/org/nocturne/main/ParametersInjector.java
index cb3d617..75cc82f 100644
--- a/code/src/main/java/org/nocturne/main/ParametersInjector.java
+++ b/code/src/main/java/org/nocturne/main/ParametersInjector.java
@@ -5,6 +5,7 @@
import com.google.common.base.Preconditions;
import net.sf.cglib.reflect.FastMethod;
+import org.apache.log4j.Logger;
import org.jetbrains.annotations.Contract;
import org.nocturne.annotation.Parameter;
import org.nocturne.exception.ConfigurationException;
@@ -35,6 +36,8 @@
*/
@SuppressWarnings("WeakerAccess")
public class ParametersInjector {
+ private static final Logger logger = Logger.getLogger(ParametersInjector.class);
+
private static final Pattern INTEGRAL_VALUE_PATTERN = Pattern.compile("0|(-?[1-9][0-9]*)");
private static final Pattern REAL_VALUE_PATTERN = Pattern.compile("(0|(-?[1-9][0-9]*))((\\.[0-9]+)?)");
@@ -87,6 +90,7 @@ Object[] setupParameters(HttpServletRequest request, FastMethod method) {
Annotation[][] parameterAnnotations = method.getJavaMethod().getParameterAnnotations();
if (parameterTypes.length != parameterAnnotations.length) {
+ logger.error("Expected the same number of parameters and annotations.");
throw new NocturneException("Expected the same number of parameters and annotations.");
}
@@ -101,10 +105,14 @@ Object[] setupParameters(HttpServletRequest request, FastMethod method) {
}
}
if (parameter == null) {
+ logger.error("Each parameter of the method " + method.getDeclaringClass().getName()
+ + '#' + method.getName() + " should be annotated with @Parameter.");
throw new ConfigurationException("Each parameter of the method " + method.getDeclaringClass().getName()
+ '#' + method.getName() + " should be annotated with @Parameter.");
}
if (StringUtil.isEmpty(parameter.name())) {
+ logger.error("Each @Parameter in the method " + method.getDeclaringClass().getName()
+ + '#' + method.getName() + " should have name.");
throw new ConfigurationException("Each @Parameter in the method " + method.getDeclaringClass().getName()
+ '#' + method.getName() + " should have name.");
}
@@ -364,10 +372,12 @@ private void setFieldValue(InjectField field, @Nullable Object assign) {
try {
field.field.set(component, assign);
} catch (IllegalAccessException e) {
- throw new IllegalArgumentException(String.format(
+ String message = String.format(
"Don't have access to set field %s of %s.",
field.field.getName(), field.field.getDeclaringClass().getName()
- ), e);
+ );
+ logger.error(message, e);
+ throw new IllegalArgumentException(message, e);
}
}
}
diff --git a/code/src/main/java/org/nocturne/main/ReloadingContext.java b/code/src/main/java/org/nocturne/main/ReloadingContext.java
index 0ac1e0d..36bdd4a 100644
--- a/code/src/main/java/org/nocturne/main/ReloadingContext.java
+++ b/code/src/main/java/org/nocturne/main/ReloadingContext.java
@@ -3,6 +3,7 @@
*/
package org.nocturne.main;
+import org.apache.log4j.Logger;
import org.nocturne.exception.ConfigurationException;
import java.io.File;
@@ -16,6 +17,8 @@
*/
@SuppressWarnings({"unused", "WeakerAccess"})
public class ReloadingContext {
+ private static final Logger logger = Logger.getLogger(ReloadingContext.class);
+
private static final ReloadingContext INSTANCE = new ReloadingContext();
private static final AtomicBoolean initialized = new AtomicBoolean(false);
@@ -101,6 +104,7 @@ void setClassReloadingExceptions(List classReloadingExceptions) {
void addReloadingClassPath(File dir) {
if (!dir.isDirectory()) {
+ logger.error("Path " + dir.getName() + " expected to be a directory.");
throw new ConfigurationException("Path " + dir.getName() + " expected to be a directory.");
}
if (!reloadingClassPaths.contains(dir)) {
diff --git a/code/src/main/java/org/nocturne/main/ReloadingContextLoader.java b/code/src/main/java/org/nocturne/main/ReloadingContextLoader.java
index b10966f..09a7c81 100644
--- a/code/src/main/java/org/nocturne/main/ReloadingContextLoader.java
+++ b/code/src/main/java/org/nocturne/main/ReloadingContextLoader.java
@@ -3,6 +3,7 @@
*/
package org.nocturne.main;
+import org.apache.log4j.Logger;
import org.nocturne.exception.ConfigurationException;
import org.nocturne.prometheus.Prometheus;
@@ -19,6 +20,8 @@
* @author Mike Mirzayanov
*/
class ReloadingContextLoader {
+ private static final Logger logger = Logger.getLogger(ReloadingContextLoader.class);
+
private static final Properties properties = new Properties();
static void run() {
@@ -38,10 +41,12 @@ private static void setupTemplates() {
try {
int templatesUpdateDelay = Integer.parseInt(properties.getProperty("nocturne.templates-update-delay"));
if (templatesUpdateDelay < 0 || templatesUpdateDelay > 86400) {
+ logger.error("Parameter nocturne.templates-update-delay should be non-negative integer not greater than 86400.");
throw new ConfigurationException("Parameter nocturne.templates-update-delay should be non-negative integer not greater than 86400.");
}
ReloadingContext.getInstance().setTemplatesUpdateDelay(templatesUpdateDelay);
} catch (NumberFormatException e) {
+ logger.error("Parameter nocturne.templates-update-delay should be integer.");
throw new ConfigurationException("Parameter nocturne.templates-update-delay should be integer.");
}
}
@@ -72,6 +77,7 @@ private static void setupSkipRegex() {
try {
ReloadingContext.getInstance().setSkipRegex(Pattern.compile(regex));
} catch (PatternSyntaxException e) {
+ logger.error("Parameter nocturne.skip-regex contains invalid pattern.");
throw new ConfigurationException("Parameter nocturne.skip-regex contains invalid pattern.");
}
}
@@ -105,6 +111,8 @@ private static void setupReloadingClassPaths() {
if (!dir.isEmpty()) {
File file = new File(dir);
if (!file.isDirectory() && ReloadingContext.getInstance().isDebug()) {
+ logger.error("Each item in nocturne.reloading-class-paths should be a directory,"
+ + " but '" + file + "' isn't.");
throw new ConfigurationException("Each item in nocturne.reloading-class-paths should be a directory,"
+ " but '" + file + "' isn't.");
}
@@ -123,6 +131,7 @@ private static void setupDebug() {
try {
debug = Boolean.parseBoolean(properties.getProperty("nocturne.debug"));
} catch (NullPointerException e) {
+ logger.error("Can't cast nocturne.debug to boolean.");
throw new ConfigurationException("Can't cast nocturne.debug to boolean.");
}
}
@@ -135,6 +144,7 @@ private static void setupDebug() {
try (InputStream inputStream = ApplicationContextLoader.class.getResourceAsStream(Constants.CONFIGURATION_FILE)) {
properties.load(inputStream);
} catch (IOException e) {
+ logger.error("Can't load resource file " + Constants.CONFIGURATION_FILE + '.', e);
throw new ConfigurationException("Can't load resource file " + Constants.CONFIGURATION_FILE + '.', e);
}
}
diff --git a/code/src/main/java/org/nocturne/module/PreprocessFreemarkerFileTemplateLoader.java b/code/src/main/java/org/nocturne/module/PreprocessFreemarkerFileTemplateLoader.java
index 995fb94..e76c01f 100644
--- a/code/src/main/java/org/nocturne/module/PreprocessFreemarkerFileTemplateLoader.java
+++ b/code/src/main/java/org/nocturne/module/PreprocessFreemarkerFileTemplateLoader.java
@@ -31,6 +31,9 @@
*/
@SuppressWarnings({"WeakerAccess", "unused"})
public class PreprocessFreemarkerFileTemplateLoader extends MultiTemplateLoader {
+ private static final org.apache.log4j.Logger logger
+ = org.apache.log4j.Logger.getLogger(PreprocessFreemarkerFileTemplateLoader.class);
+
private static final ConcurrentMap templateSourceByName = new ConcurrentHashMap<>();
private final int templateDirCount;
@@ -42,6 +45,7 @@ public PreprocessFreemarkerFileTemplateLoader(File... templateDirs) throws IOExc
private static TemplateLoader[] getTemplateLoaders(File[] templateDirs) throws IOException {
int templateDirCount = templateDirs.length;
if (templateDirCount <= 0) {
+ logger.error("Please specify at least one template directory.");
throw new ConfigurationException("Please specify at least one template directory.");
}
@@ -127,6 +131,7 @@ private static void processCaptions(StringBuilder sb) {
String content = sb.substring(index + 2, closeIndex);
if (content.startsWith("!")) {
+ logger.error("{{!...}} syntax is no more supported.");
throw new UnsupportedOperationException("{{!...}} syntax is no more supported.");
}
diff --git a/code/src/main/java/org/nocturne/reset/FieldsResetter.java b/code/src/main/java/org/nocturne/reset/FieldsResetter.java
index 2420fdc..eb500d0 100644
--- a/code/src/main/java/org/nocturne/reset/FieldsResetter.java
+++ b/code/src/main/java/org/nocturne/reset/FieldsResetter.java
@@ -17,6 +17,8 @@
* @author Mike Mirzayanov
*/
abstract class FieldsResetter {
+ private static final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(FieldsResetter.class);
+
private static final Map, Object> PRIMITIVES_DEFAULT_VALUES = new ConcurrentHashMap<>();
private static final ConcurrentMap RESET_ANNOTATIONS_CACHE = new ConcurrentHashMap<>();
private static final ConcurrentMap PERSIST_ANNOTATIONS_CACHE = new ConcurrentHashMap<>();
@@ -144,6 +146,7 @@ private void resetPrimitiveField(Field field) {
private static ResetStrategy getStrategy(
ResetStrategy defaultStrategy, boolean hasReset, boolean hasPersist, String name) {
if (hasPersist && hasReset) {
+ logger.error("It is impossible to use Reset and Persist at the same time [name=" + name + "].");
throw new ConfigurationException("It is impossible to use " +
"Reset and Persist at the same time [name=" + name + "].");
}