Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Override app settings stored into the embedded DB #fixed 270

  • Loading branch information...
commit 74b115db1969f9aeae12e503dde5ab3b006b5c3e 2 parents e1d0338 + 4a1d5ee
@giastfader giastfader authored
Showing with 744 additions and 119 deletions.
  1. +63 −62 app/com/baasbox/Global.java
  2. +68 −4 app/com/baasbox/configuration/Application.java
  3. +16 −0 app/com/baasbox/configuration/IProperties.java
  4. +66 −1 app/com/baasbox/configuration/ImagesConfiguration.java
  5. +53 −1 app/com/baasbox/configuration/Internal.java
  6. +69 −2 app/com/baasbox/configuration/PasswordRecovery.java
  7. +109 −30 app/com/baasbox/configuration/PropertiesConfigurationHelper.java
  8. +68 −1 app/com/baasbox/configuration/Push.java
  9. +69 −2 app/com/baasbox/configuration/SocialLoginConfiguration.java
  10. +1 −1  app/com/baasbox/configuration/{ → index}/IndexApplicationConfiguration.java
  11. +1 −1  app/com/baasbox/configuration/{ → index}/IndexImageConfiguration.java
  12. +1 −1  app/com/baasbox/configuration/{ → index}/IndexInternalConfiguration.java
  13. +1 −1  app/com/baasbox/configuration/{ → index}/IndexPasswordRecoveryConfiguration.java
  14. +2 −2 app/com/baasbox/configuration/{ → index}/IndexPushConfiguration.java
  15. +1 −1  app/com/baasbox/configuration/{ → index}/IndexSocialLoginConfiguration.java
  16. +2 −0  app/com/baasbox/controllers/Admin.java
  17. +3 −3 app/com/baasbox/db/DbHelper.java
  18. +1 −1  app/com/baasbox/db/Evolution_0_7_0.java
  19. 0  ...om/baasbox/{controllers/actions/filters/accesslog/AccessLogFilter.scala → filters/LoggingFilter.scala}
  20. +5 −0 conf/application.conf
  21. +8 −5 public/console/bbjs/baasboxgui.js
  22. +137 −0 test/OverrideSettingsTest.java
View
125 app/com/baasbox/Global.java
@@ -23,7 +23,8 @@
import static play.mvc.Results.internalServerError;
import static play.mvc.Results.notFound;
-import java.io.UnsupportedEncodingException;
+import java.util.Iterator;
+import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
@@ -41,19 +42,22 @@
import play.mvc.Http.RequestHeader;
import play.mvc.Result;
+import com.baasbox.configuration.IProperties;
import com.baasbox.configuration.Internal;
import com.baasbox.configuration.IosCertificateHandler;
+import com.baasbox.configuration.PropertiesConfigurationHelper;
import com.baasbox.db.DbHelper;
+import com.baasbox.exception.ConfigurationException;
import com.baasbox.security.ISessionTokenProvider;
import com.baasbox.security.SessionTokenProvider;
import com.baasbox.service.storage.StatisticsService;
+import com.baasbox.util.ConfigurationFileContainer;
import com.orientechnologies.orient.core.Orient;
import com.orientechnologies.orient.core.config.OGlobalConfiguration;
import com.orientechnologies.orient.core.db.document.ODatabaseDocumentPool;
import com.orientechnologies.orient.core.db.graph.OGraphDatabase;
import com.orientechnologies.orient.core.db.record.ODatabaseRecordTx;
import com.orientechnologies.orient.core.exception.ODatabaseException;
-import com.typesafe.config.ConfigException;
public class Global extends GlobalSettings {
@@ -180,6 +184,9 @@ public void onStart(Application app) {
if (db!=null && !db.isClosed()) db.close();
}
info ("...done");
+
+ overrideSettings();
+
info("BaasBox is Ready.");
String port=Play.application().configuration().getString("http.port");
if (port==null) port="9000";
@@ -192,6 +199,58 @@ public void onStart(Application app) {
info("Documentation is available at http://www.baasbox.com/documentation");
debug("Global.onStart() ended");
}
+
+ private void overrideSettings() {
+ info ("Override settings...");
+ //takes only the settings that begin with baasbox.settings
+ Configuration bbSettingsToOverride=BBConfiguration.configuration.getConfig("baasbox.settings");
+ //if there is at least one of them
+ if (bbSettingsToOverride!=null) {
+ //takes the part after the "baasbox.settings" of the key names
+ Set<String> keys = bbSettingsToOverride.keys();
+ Iterator<String> keysIt = keys.iterator();
+ //for each setting to override
+ while (keysIt.hasNext()){
+ String key = keysIt.next();
+ //is it a value to override?
+ if (key.endsWith(".value")){
+ //sets the overridden value
+ String value = "";
+ try {
+ value = bbSettingsToOverride.getString(key);
+ key = key.substring(0, key.lastIndexOf(".value"));
+ PropertiesConfigurationHelper.override(key,value);
+ } catch (Exception e) {
+ error ("Error overriding the setting " + key + " with the value " + value.toString() + ": " +e.getMessage());
+ }
+ }else if (key.endsWith(".visible")){ //or maybe we have to hide it when a REST API is called
+ //sets the visibility
+ Boolean value;
+ try {
+ value = bbSettingsToOverride.getBoolean(key);
+ key = key.substring(0, key.lastIndexOf(".visible"));
+ PropertiesConfigurationHelper.setVisible(key,value);
+ } catch (Exception e) {
+ error ("Error overriding the visible attribute for setting " + key + ": " +e.getMessage());
+ }
+ }else if (key.endsWith(".editable")){ //or maybe we have to
+ //sets the possibility to edit the value via REST API by the admin
+ Boolean value;
+ try {
+ value = bbSettingsToOverride.getBoolean(key);
+ key = key.substring(0, key.lastIndexOf(".editable"));
+ PropertiesConfigurationHelper.setEditable(key,value);
+ } catch (Exception e) {
+ error ("Error overriding the editable attribute setting " + key + ": " +e.getMessage());
+ }
+ }else {
+ error("The configuration key: " + key + " is invalid. value, visible or editable are missing");
+ }
+ key.subSequence(0, key.lastIndexOf("."));
+ }
+ }else info ("...No setting to override...");
+ info ("...done");
+ }
@@ -277,67 +336,9 @@ public Result onError(RequestHeader request, Throwable throwable) {
}
- @Override
+ @Override
public <T extends EssentialFilter> Class<T>[] filters() {
return new Class[]{com.baasbox.filters.LoggingFilter.class};
}
-
-
-
-
-
-
- //these are needed to override the standard action calls and to centralized the errors response
- //TODO: we must implement the Play! 2.1 Filters
- /*
- @Override
- public Action onRequest(Request request, Method actionMethod) {
- return new ActionWrapper(super.onRequest(request, actionMethod));
- }
-
- private class ActionWrapper extends Action.Simple {
- public ActionWrapper(Action action) {
- this.delegate = action;
- }
-
- @Override
- public Result call(Context ctx) throws Throwable {
- Http.Context.current.set(ctx);
- //injects the CORS header
- ctx.response().setHeader("Access-Control-Allow-Origin", "*");
- //injects the user data & credential into the context
- String token=ctx.request().getHeader(SessionKeys.TOKEN.toString());
- if (token!=null) {
- ImmutableMap<SessionKeys, ? extends Object> sessionData = SessionTokenProvider.getSessionTokenProvider().getSession(token);
- if (sessionData!=null){
- ctx.args.put("username", sessionData.get(SessionKeys.USERNAME));
- ctx.args.put("password", sessionData.get(SessionKeys.PASSWORD));
- ctx.args.put("appcode", sessionData.get(SessionKeys.APP_CODE));
- }
- }
-
- //executes the request
- Result result = this.delegate.call(ctx);
-
- //checks the result of the request
- final int statusCode = JavaResultExtractor.getStatus(result);
- if (statusCode>399){ //an error occured
- final byte[] body = JavaResultExtractor.getBody(result);
- String stringBody = new String(body, "UTF-8");
- switch (statusCode) {
- case 400: return onBadRequest(ctx.request(),stringBody);
- case 401: return onUnauthorized(ctx.request(),stringBody);
- case 403: return onForbidden(ctx.request(),stringBody);
- case 404: return onResourceNotFound(ctx.request(),stringBody);
- default: return onDefaultError(statusCode,ctx.request(),stringBody);
- }
- }
- return result;
- //play.api.mvc.SimpleResult wrappedResult = (play.api.mvc.SimpleResult) result.getWrappedResult();
- //Response response = ctx.response();
- }//call
- }//class ActionWrapper
- */
-
-}
+}
View
72 app/com/baasbox/configuration/Application.java
@@ -2,6 +2,7 @@
import play.Logger;
+import com.baasbox.configuration.index.IndexApplicationConfiguration;
import com.baasbox.security.ISessionTokenProvider;
import com.baasbox.security.SessionTokenProvider;
@@ -25,9 +26,14 @@ public void change(final Object iCurrentValue, final Object iNewValue){
private final Class<?> type;
private String description;
private IPropertyChangeCallback changeCallback = null;
+
+ //override
+ private boolean editable=true;
+ private boolean visible=true;
+ private Object overriddenValue=null;
+ private boolean overridden=false;
-
- Application(final String iKey, final String iDescription, final Class<?> iType,
+ Application(final String iKey, final String iDescription, final Class<?> iType,
final IPropertyChangeCallback iChangeAction) {
this(iKey, iDescription, iType);
changeCallback = iChangeAction;
@@ -40,9 +46,14 @@ public void change(final Object iCurrentValue, final Object iNewValue){
}
@Override
- public void setValue(Object newValue) {
- Object parsedValue=null;
+ public void setValue(Object newValue) throws IllegalStateException{
+ if (!editable) throw new IllegalStateException("The value cannot be changed");
+ _setValue(newValue);
+ }
+ @Override
+ public void _setValue(Object newValue) {
+ Object parsedValue=null;
if (Logger.isDebugEnabled()) Logger.debug("New setting value, key: " + this.key + ", type: "+ this.type + ", new value: " + newValue);
if (newValue != null)
if (type == Boolean.class)
@@ -63,11 +74,18 @@ else if (type == String.class)
idx.put(key, parsedValue);
} catch (Exception e) {
Logger.error("Could not store key " + key, e);
+ throw new RuntimeException("Could not store key " + key,e);
}
}
@Override
public Object getValue() {
+ if (overridden) return overriddenValue;
+ return _getValue();
+ }
+
+ @Override
+ public Object _getValue() {
IndexApplicationConfiguration idx;
try {
idx = new IndexApplicationConfiguration();
@@ -130,4 +148,50 @@ public static String getEnumDescription() {
return "Configurations for general App(lication) related properties";
}
+ @Override
+ public void override(Object newValue) {
+ Object parsedValue=null;
+
+ if (Logger.isDebugEnabled()) Logger.debug("New setting value, key: " + this.key + ", type: "+ this.type + ", new value: " + newValue);
+ if (newValue != null)
+ if (type == Boolean.class)
+ parsedValue = Boolean.parseBoolean(newValue.toString());
+ else if (type == Integer.class)
+ parsedValue = Integer.parseInt(newValue.toString());
+ else if (type == Float.class)
+ parsedValue = Float.parseFloat(newValue.toString());
+ else if (type == String.class)
+ parsedValue = newValue.toString();
+ else
+ parsedValue = newValue;
+ this.overriddenValue=parsedValue;
+ this.overridden=true;
+ this.editable=false;
+ }
+
+ @Override
+ public void setEditable(boolean editable) {
+ this.editable = editable;
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ this.visible = visible;
+ }
+
+ @Override
+ public boolean isOverridden() {
+ return overridden;
+ }
+
+ @Override
+ public boolean isVisible() {
+ return visible;
+ }
+
+ @Override
+ public boolean isEditable() {
+ return editable;
+ }
+
}
View
16 app/com/baasbox/configuration/IProperties.java
@@ -4,7 +4,17 @@
public interface IProperties {
public void setValue(final Object iValue);
+ /***
+ * internal use only, sets the original value bypassing the editable flag and the overridden value
+ * @param iValue
+ */
+ public void _setValue(final Object iValue);
public Object getValue();
+ /***
+ * internal use only, bypass the overridden value returning the real one
+ * @return
+ */
+ public Object _getValue();
public boolean getValueAsBoolean();
public String getValueAsString();
public int getValueAsInteger();
@@ -13,4 +23,10 @@
public String getKey();
public Class<?> getType();
public String getValueDescription();
+ public void override(Object newValue) ;
+ public boolean isVisible();
+ public boolean isEditable();
+ public void setEditable(boolean value);
+ public void setVisible(boolean value);
+ public boolean isOverridden();
}
View
67 app/com/baasbox/configuration/ImagesConfiguration.java
@@ -5,6 +5,8 @@
import org.apache.regexp.RE;
import org.apache.regexp.RESyntaxException;
+import com.baasbox.configuration.index.IndexPasswordRecoveryConfiguration;
+
import play.Logger;
public enum ImagesConfiguration implements IProperties{
@@ -39,6 +41,11 @@ public void change(final Object iCurrentValue, final Object iNewValue){
private String description;
private IPropertyChangeCallback changeCallback = null;
+ //override
+ private boolean editable=true;
+ private boolean visible=true;
+ private Object overriddenValue=null;
+ private boolean overridden=false;
ImagesConfiguration(final String iKey, final String iDescription, final Class<?> iType,
final IPropertyChangeCallback iChangeAction) {
@@ -53,7 +60,13 @@ public void change(final Object iCurrentValue, final Object iNewValue){
}
@Override
- public void setValue(Object newValue) {
+ public void setValue(Object newValue) throws IllegalStateException{
+ if (!editable) throw new IllegalStateException("The value cannot be changed");
+ _setValue(newValue);
+ }
+
+ @Override
+ public void _setValue(Object newValue) {
Object parsedValue=null;
if (newValue != null)
@@ -75,11 +88,18 @@ else if (type == String.class)
idx.put(key, parsedValue);
} catch (Exception e) {
Logger.error("Could not store key " + key, e);
+ throw new RuntimeException("Could not store key " + key,e);
}
}
@Override
public Object getValue() {
+ if (overridden) return overriddenValue;
+ return _getValue();
+ }
+
+ @Override
+ public Object _getValue() {
IndexPasswordRecoveryConfiguration idx;
try {
idx = new IndexPasswordRecoveryConfiguration();
@@ -140,5 +160,50 @@ public String getValueDescription() {
public static String getEnumDescription() {
return "Configurations for Images related stuffs";
}
+
+ @Override
+ public void override(Object newValue) {
+ Object parsedValue=null;
+ if (Logger.isDebugEnabled()) Logger.debug("New setting value, key: " + this.key + ", type: "+ this.type + ", new value: " + newValue);
+ if (newValue != null)
+ if (type == Boolean.class)
+ parsedValue = Boolean.parseBoolean(newValue.toString());
+ else if (type == Integer.class)
+ parsedValue = Integer.parseInt(newValue.toString());
+ else if (type == Float.class)
+ parsedValue = Float.parseFloat(newValue.toString());
+ else if (type == String.class)
+ parsedValue = newValue.toString();
+ else
+ parsedValue = newValue;
+ this.overriddenValue=parsedValue;
+ this.overridden=true;
+ this.editable=false;
+ }
+
+ @Override
+ public boolean isVisible() {
+ return visible;
+ }
+
+ @Override
+ public boolean isEditable() {
+ return editable;
+ }
+
+ @Override
+ public boolean isOverridden() {
+ return overridden;
+ }
+
+ @Override
+ public void setEditable(boolean editable) {
+ this.editable = editable;
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ this.visible = visible;
+ }
}
View
54 app/com/baasbox/configuration/Internal.java
@@ -1,5 +1,7 @@
package com.baasbox.configuration;
+import com.baasbox.configuration.index.IndexInternalConfiguration;
+
import play.Logger;
@@ -18,6 +20,12 @@
private String description;
private IPropertyChangeCallback changeCallback = null;
+ //override
+ private boolean editable=false;
+ private boolean visible=true;
+ private Object overriddenValue=null;
+ private boolean overridden=false;
+
Internal(final String iKey, final String iDescription, final Class<?> iType,
final IPropertyChangeCallback iChangeAction) {
@@ -33,8 +41,13 @@
@Override
public void setValue(Object newValue) {
- Object parsedValue=null;
+ if (!editable) throw new IllegalStateException("The value cannot be changed");
+ _setValue(newValue);
+ }
+ @Override
+ public void _setValue(Object newValue) {
+ Object parsedValue=null;
if (newValue != null)
if (type == Boolean.class)
parsedValue = Boolean.parseBoolean(newValue.toString());
@@ -54,11 +67,18 @@ else if (type == String.class)
idx.put(key, parsedValue);
} catch (Exception e) {
Logger.error("Could not store key " + key, e);
+ throw new RuntimeException("Could not store key " + key,e);
}
}
@Override
public Object getValue() {
+ if (overridden) return overriddenValue;
+ return _getValue();
+ }
+
+ @Override
+ public Object _getValue() {
IndexInternalConfiguration idx;
try {
idx = new IndexInternalConfiguration();
@@ -119,5 +139,37 @@ public String getValueDescription() {
public static String getEnumDescription() {
return "Internal <key/value>, intended for internal usage only";
}
+
+ @Override
+ public void override(Object newValue) {
+ throw new IllegalStateException ("Cannot override this value");
+ }
+
+ @Override
+ public boolean isVisible() {
+ return visible;
+ }
+
+ @Override
+ public boolean isEditable() {
+ return editable;
+ }
+
+ @Override
+ public boolean isOverridden() {
+ return overridden;
+ }
+
+ @Override
+ public void setEditable(boolean editable) {
+ throw new IllegalStateException ("Cannot override this value");
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ this.visible = visible;
+ }
+
+
}
View
71 app/com/baasbox/configuration/PasswordRecovery.java
@@ -1,8 +1,11 @@
package com.baasbox.configuration;
import play.Logger;
+
import org.apache.commons.lang3.BooleanUtils;
+import com.baasbox.configuration.index.IndexPasswordRecoveryConfiguration;
+
public enum PasswordRecovery implements IProperties{
EMAIL_TEMPLATE_TEXT("email.template.text", "The template (text format) of the email to send to the user when they request a password reset. Please ensure that you have written the keyword $link$ inside the text. This keyword will be replaced with the link that the user has to click on to start the password recovery process.", String.class),
@@ -27,7 +30,12 @@
private String description;
private IPropertyChangeCallback changeCallback = null;
-
+ //override
+ private boolean editable=true;
+ private boolean visible=true;
+ private Object overriddenValue=null;
+ private boolean overridden=false;
+
PasswordRecovery(final String iKey, final String iDescription, final Class<?> iType,
final IPropertyChangeCallback iChangeAction) {
this(iKey, iDescription, iType);
@@ -41,7 +49,13 @@
}
@Override
- public void setValue(Object newValue) {
+ public void setValue(Object newValue) throws IllegalStateException{
+ if (!editable) throw new IllegalStateException("The value cannot be changed");
+ _setValue(newValue);
+ }
+
+ @Override
+ public void _setValue(Object newValue) {
Object parsedValue=null;
try{
@@ -66,11 +80,18 @@ else if (type == String.class)
idx.put(key, parsedValue);
} catch (Exception e) {
Logger.error("Could not store key " + key, e);
+ throw new RuntimeException("Could not store key " + key,e);
}
}
@Override
public Object getValue() {
+ if (overridden) return overriddenValue;
+ return _getValue();
+ }
+
+ @Override
+ public Object _getValue() {
IndexPasswordRecoveryConfiguration idx;
try {
idx = new IndexPasswordRecoveryConfiguration();
@@ -132,5 +153,51 @@ public String getValueDescription() {
public static String getEnumDescription() {
return "Configurations for password recovery related properties";
}
+ @Override
+ public void override(Object newValue) {
+ Object parsedValue=null;
+
+ if (Logger.isDebugEnabled()) Logger.debug("New setting value, key: " + this.key + ", type: "+ this.type + ", new value: " + newValue);
+ if (newValue != null)
+ if (type == Boolean.class)
+ parsedValue = Boolean.parseBoolean(newValue.toString());
+ else if (type == Integer.class)
+ parsedValue = Integer.parseInt(newValue.toString());
+ else if (type == Float.class)
+ parsedValue = Float.parseFloat(newValue.toString());
+ else if (type == String.class)
+ parsedValue = newValue.toString();
+ else
+ parsedValue = newValue;
+ this.overriddenValue=parsedValue;
+ this.overridden=true;
+ this.editable=false;
+ }
+
+ @Override
+ public void setEditable(boolean editable) {
+ this.editable = editable;
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ this.visible = visible;
+ }
+
+
+ @Override
+ public boolean isOverridden() {
+ return overridden;
+ }
+
+ @Override
+ public boolean isVisible() {
+ return visible;
+ }
+
+ @Override
+ public boolean isEditable() {
+ return editable;
+ }
}
View
139 app/com/baasbox/configuration/PropertiesConfigurationHelper.java
@@ -1,11 +1,12 @@
package com.baasbox.configuration;
import java.io.StringWriter;
-import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.util.Arrays;
import java.util.EnumSet;
+import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonParser;
@@ -64,7 +65,11 @@ public static String dumpConfigurationAsJson(String section) {
EnumSet values = EnumSet.allOf( en );
for (Object v : values) {
String key=(String) (en.getMethod("getKey")).invoke(v);
- String valueAsString=(String) (en.getMethod("getValueAsString")).invoke(v);
+ boolean isVisible=(Boolean)(en.getMethod("isVisible")).invoke(v);
+ String valueAsString;
+ if (isVisible) valueAsString=(String) (en.getMethod("getValueAsString")).invoke(v);
+ else valueAsString = "--HIDDEN--";
+ boolean isEditable=(Boolean)(en.getMethod("isEditable")).invoke(v);
String valueDescription=(String) (en.getMethod("getValueDescription")).invoke(v);
Class type = (Class) en.getMethod("getType").invoke(v);
String subsection = key.substring(0, key.indexOf('.'));
@@ -74,10 +79,14 @@ public static String dumpConfigurationAsJson(String section) {
gen.writeStartArray(); // [
lastSection = subsection;
}
+ boolean isOverridden = (Boolean)(en.getMethod("isOverridden")).invoke(v);
gen.writeStartObject(); // {
gen.writeStringField(key,valueAsString); // "key": "value"
gen.writeStringField("description", valueDescription); // ,"description":"description"
gen.writeStringField("type",type.getSimpleName()); // ,"type":"type"
+ gen.writeBooleanField("editable",isEditable); // ,"editable":"true|false"
+ gen.writeBooleanField("visible",isVisible); // ,"visible":"true|false"
+ gen.writeBooleanField("overridden",isOverridden); // ,"overridden":"true|false"
gen.writeEndObject(); // }
}
if (gen.getOutputContext().inArray()) gen.writeEndArray(); // ]
@@ -166,6 +175,46 @@ public static String dumpConfiguration(String section) {
return "";
}//dumpConfiguration
+ public static String dumpConfigurationSectionAsFlatJson(String section){
+ Class en = CONFIGURATION_SECTIONS.get(section);
+ try {
+ JsonFactory jfactory = new JsonFactory();
+ StringWriter sw = new StringWriter();
+ String enumDescription = "";
+ JsonGenerator gen = jfactory.createJsonGenerator(sw);
+ gen.writeStartArray();
+ EnumSet values = EnumSet.allOf( en );
+ for (Object v : values) {
+ String key=(String) (en.getMethod("getKey")).invoke(v);
+
+
+ boolean isVisible=(Boolean)(en.getMethod("isVisible")).invoke(v);
+ String valueAsString;
+ if (isVisible) valueAsString=(String) (en.getMethod("getValueAsString")).invoke(v);
+ else valueAsString = "--HIDDEN--";
+ boolean isEditable=(Boolean)(en.getMethod("isEditable")).invoke(v);
+ boolean isOverridden = (Boolean)(en.getMethod("isOverridden")).invoke(v);
+ String valueDescription=(String) (en.getMethod("getValueDescription")).invoke(v);
+ Class type = (Class) en.getMethod("getType").invoke(v);
+
+ gen.writeStartObject(); // {
+ gen.writeStringField("key", key);
+ gen.writeStringField("value",valueAsString);
+ gen.writeStringField("description", valueDescription); // ,"description":"description"
+ gen.writeStringField("type",type.getSimpleName()); // ,"type":"type"
+ gen.writeBooleanField("editable", isEditable);
+ gen.writeBooleanField("overridden", isOverridden);
+ gen.writeEndObject(); // }
+ }
+ if (gen.getOutputContext().inArray()) gen.writeEndArray(); // ]
+ gen.close();
+ return sw.toString();
+ } catch (Exception e) {
+ Logger.error("Cannot generate a json for "+ en.getSimpleName()+" Enum. Is it an Enum that implements the IProperties interface?",e);
+ }
+ return "{}";
+ }//dumpConfigurationSectionAsJson(String)()
+
/***
* Returns an Enumerator value by its key
* The Enumerator must implement the IProperties interface
@@ -187,6 +236,25 @@ public static Object findByKey(Class en,String iKey) throws ConfigurationExcepti
}
return null;
} //findByKey
+
+
+ public static Object findByKey(String completeKey) throws ConfigurationException {
+ String[] splittedKeys=completeKey.split("\\.");
+ String section=splittedKeys[0];
+ Class en = PropertiesConfigurationHelper.CONFIGURATION_SECTIONS.get(section);
+ EnumSet values = EnumSet.allOf( en );
+ for (Object v : values) {
+ try {
+ String key=StringUtils.join(Arrays.copyOfRange(splittedKeys, 1, splittedKeys.length),".");
+ if ( ((String)en.getMethod("getKey").invoke(v)).equalsIgnoreCase(key) )
+ return v;
+ } catch (Exception e) {
+ throw new ConfigurationException ("Is it " + en.getCanonicalName() + " an Enum that implements the IProperties interface?",e );
+ }
+ }
+ return null;
+ } //findByKey
+
/***
* Set an Enumerator value.
@@ -197,43 +265,54 @@ public static Object findByKey(Class en,String iKey) throws ConfigurationExcepti
* @throws ConfigurationException
* @throws Exception
*/
- public static void setByKey(Class en,String iKey,Object value) throws ConfigurationException {
+ public static void setByKey(Class en,String iKey,Object value) throws IllegalStateException,ConfigurationException {
Object enumValue = findByKey(en,iKey);
try {
en.getMethod("setValue",Object.class).invoke(enumValue,value);
- } catch (Exception e) {
+
+ }catch (Exception e) {
+ if (e.getCause() instanceof IllegalStateException) throw new IllegalStateException(e.getCause());
throw new ConfigurationException ("Invalid key -" +iKey+ "- or value -" +value+"-" ,e );
}
} //setByKey
- public static String dumpConfigurationSectionAsFlatJson(String section){
- Class en = CONFIGURATION_SECTIONS.get(section);
+ public static void override(String completeKey,Object value) throws ConfigurationException {
+ Object enumValue = findByKey(completeKey);
try {
- JsonFactory jfactory = new JsonFactory();
- StringWriter sw = new StringWriter();
- String enumDescription = "";
- JsonGenerator gen = jfactory.createJsonGenerator(sw);
- gen.writeStartArray();
- EnumSet values = EnumSet.allOf( en );
- for (Object v : values) {
- String key=(String) (en.getMethod("getKey")).invoke(v);
- String valueAsString=(String) (en.getMethod("getValueAsString")).invoke(v);
- String valueDescription=(String) (en.getMethod("getValueDescription")).invoke(v);
- Class type = (Class) en.getMethod("getType").invoke(v);
- gen.writeStartObject(); // {
- gen.writeStringField("key", key);
- gen.writeStringField("value",valueAsString);
- gen.writeStringField("description", valueDescription); // ,"description":"description"
- gen.writeStringField("type",type.getSimpleName()); // ,"type":"type"
- gen.writeEndObject(); // }
- }
- if (gen.getOutputContext().inArray()) gen.writeEndArray(); // ]
- gen.close();
- return sw.toString();
+ String[] splittedKeys=completeKey.split("\\.");
+ String section=splittedKeys[0];
+ Class en = PropertiesConfigurationHelper.CONFIGURATION_SECTIONS.get(section);
+ en.getMethod("override",Object.class).invoke(enumValue,value);
} catch (Exception e) {
- Logger.error("Cannot generate a json for "+ en.getSimpleName()+" Enum. Is it an Enum that implements the IProperties interface?",e);
+ throw new ConfigurationException ("Invalid key -" +completeKey+ "- or value -" +value+"-" ,e );
}
- return "{}";
- }//dumpConfigurationSectionAsJson(String)()
+ }
+
+
+ public static void setVisible(String completeKey, Boolean value) throws ConfigurationException {
+ Object enumValue = findByKey(completeKey);
+ try {
+ String[] splittedKeys=completeKey.split("\\.");
+ String section=splittedKeys[0];
+ Class en = PropertiesConfigurationHelper.CONFIGURATION_SECTIONS.get(section);
+ en.getMethod("setVisible",boolean.class).invoke(enumValue,value);
+ } catch (Exception e) {
+ Logger.error("Invalid key -" +completeKey+ "- or value -" +value+"-",e);
+ throw new ConfigurationException ("Invalid key -" +completeKey+ "- or value -" +value+"-" ,e );
+ }
+ }
+
+ public static void setEditable(String completeKey, Boolean value) throws ConfigurationException {
+ Object enumValue = findByKey(completeKey);
+ try {
+ String[] splittedKeys=completeKey.split("\\.");
+ String section=splittedKeys[0];
+ Class en = PropertiesConfigurationHelper.CONFIGURATION_SECTIONS.get(section);
+ en.getMethod("setEditable",boolean.class).invoke(enumValue,value);
+ } catch (Exception e) {
+ Logger.error("Invalid key -" +completeKey+ "- or value -" +value+"-",e);
+ throw new ConfigurationException ("Invalid key -" +completeKey+ "- or value -" +value+"-" ,e );
+ }
+ }
}//PropertiesConfigurationHelper
View
69 app/com/baasbox/configuration/Push.java
@@ -4,6 +4,7 @@
import play.Logger;
+import com.baasbox.configuration.index.IndexPushConfiguration;
import com.baasbox.util.ConfigurationFileContainer;
@@ -24,6 +25,12 @@
private String description;
private IPropertyChangeCallback changeCallback = null;
+ //override
+ private boolean editable=true;
+ private boolean visible=true;
+ private Object overriddenValue=null;
+ private boolean overridden=false;
+
Push(final String iKey, final String iDescription, final Class<?> iType,
final IPropertyChangeCallback iChangeAction) {
@@ -38,7 +45,13 @@
}
@Override
- public void setValue(Object newValue) {
+ public void setValue(Object newValue) throws IllegalStateException{
+ if (!editable) throw new IllegalStateException("The value cannot be changed");
+ _setValue(newValue);
+ }
+
+ @Override
+ public void _setValue(Object newValue) {
Object parsedValue=null;
if (Logger.isDebugEnabled()) Logger.debug("Type:"+type+" Setting "+newValue.toString() + "of class: "+newValue.getClass().toString());
try{
@@ -73,11 +86,18 @@ else if (type == ConfigurationFileContainer.class){
}
} catch (Exception e) {
Logger.error("Could not store key " + key, e);
+ throw new RuntimeException("Could not store key " + key,e);
}
}
@Override
public Object getValue() {
+ if (overridden) return overriddenValue;
+ return _getValue();
+ }
+
+ @Override
+ public Object _getValue() {
IndexPushConfiguration idx;
try {
@@ -154,5 +174,52 @@ public String getValueDescription() {
public static String getEnumDescription() {
return "Configurations for push related properties";
}
+
+ @Override
+ public void override(Object newValue) {
+ Object parsedValue=null;
+
+ if (Logger.isDebugEnabled()) Logger.debug("New setting value, key: " + this.key + ", type: "+ this.type + ", new value: " + newValue);
+ if (newValue != null)
+ if (type == Boolean.class)
+ parsedValue = Boolean.parseBoolean(newValue.toString());
+ else if (type == Integer.class)
+ parsedValue = Integer.parseInt(newValue.toString());
+ else if (type == Float.class)
+ parsedValue = Float.parseFloat(newValue.toString());
+ else if (type == String.class)
+ parsedValue = newValue.toString();
+ else
+ parsedValue = newValue;
+ this.overriddenValue=parsedValue;
+ this.overridden=true;
+ this.editable=false;
+ }
+
+
+ @Override
+ public void setEditable(boolean editable) {
+ this.editable = editable;
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ this.visible = visible;
+ }
+
+ @Override
+ public boolean isOverridden() {
+ return overridden;
+ }
+
+ @Override
+ public boolean isVisible() {
+ return visible;
+ }
+
+ @Override
+ public boolean isEditable() {
+ return editable;
+ }
}
View
71 app/com/baasbox/configuration/SocialLoginConfiguration.java
@@ -1,5 +1,7 @@
package com.baasbox.configuration;
+import com.baasbox.configuration.index.IndexSocialLoginConfiguration;
+
import play.Logger;
public enum SocialLoginConfiguration implements IProperties{
@@ -16,6 +18,13 @@
private String description;
private IPropertyChangeCallback changeCallback;
+ //override
+ private boolean editable=true;
+ private boolean visible=true;
+ private Object overriddenValue=null;
+ private boolean overridden=false;
+
+
SocialLoginConfiguration(final String iKey, final String iDescription, final Class<?> iType,
final IPropertyChangeCallback iChangeAction) {
this(iKey, iDescription, iType);
@@ -30,7 +39,13 @@
@Override
- public void setValue(Object newValue) {
+ public void setValue(Object newValue) throws IllegalStateException{
+ if (!editable) throw new IllegalStateException("The value cannot be changed");
+ _setValue(newValue);
+ }
+
+ @Override
+ public void _setValue(Object newValue) {
Object parsedValue=null;
if (newValue != null)
@@ -52,11 +67,18 @@ else if (type == String.class)
idx.put(key, parsedValue);
} catch (Exception e) {
Logger.error("Could not store key " + key, e);
- }
+ throw new RuntimeException("Could not store key " + key,e);
+ }
}
@Override
public Object getValue() {
+ if (overridden) return overriddenValue;
+ return _getValue();
+ }
+
+ @Override
+ public Object _getValue() {
IndexSocialLoginConfiguration idx;
try {
idx = new IndexSocialLoginConfiguration();
@@ -117,5 +139,50 @@ public String getValueDescription() {
public static String getEnumDescription() {
return "Configurations for Social Login related stuffs";
}
+
+ @Override
+ public void override(Object newValue) {
+ Object parsedValue=null;
+
+ if (Logger.isDebugEnabled()) Logger.debug("New setting value, key: " + this.key + ", type: "+ this.type + ", new value: " + newValue);
+ if (newValue != null)
+ if (type == Boolean.class)
+ parsedValue = Boolean.parseBoolean(newValue.toString());
+ else if (type == Integer.class)
+ parsedValue = Integer.parseInt(newValue.toString());
+ else if (type == Float.class)
+ parsedValue = Float.parseFloat(newValue.toString());
+ else if (type == String.class)
+ parsedValue = newValue.toString();
+ else
+ parsedValue = newValue;
+ this.overriddenValue=parsedValue;
+ this.overridden=true;
+ this.editable=false;
+ }
+
+ @Override
+ public void setEditable(boolean editable) {
+ this.editable = editable;
+ }
+
+ @Override
+ public void setVisible(boolean visible) {
+ this.visible = visible;
+ }
+ @Override
+ public boolean isVisible() {
+ return visible;
+ }
+
+ @Override
+ public boolean isOverridden() {
+ return overridden;
+ }
+
+ @Override
+ public boolean isEditable() {
+ return editable;
+ }
}
View
2  .../configuration/IndexApplicationConfiguration.java → ...guration/index/IndexApplicationConfiguration.java
@@ -1,4 +1,4 @@
- package com.baasbox.configuration;
+ package com.baasbox.configuration.index;
import com.baasbox.dao.IndexDao;
import com.baasbox.exception.IndexNotFoundException;
View
2  ...aasbox/configuration/IndexImageConfiguration.java → .../configuration/index/IndexImageConfiguration.java
@@ -1,4 +1,4 @@
-package com.baasbox.configuration;
+package com.baasbox.configuration.index;
import com.baasbox.dao.IndexDao;
import com.baasbox.exception.IndexNotFoundException;
View
2  ...box/configuration/IndexInternalConfiguration.java → ...nfiguration/index/IndexInternalConfiguration.java
@@ -1,4 +1,4 @@
- package com.baasbox.configuration;
+ package com.baasbox.configuration.index;
import com.baasbox.dao.IndexDao;
import com.baasbox.exception.IndexNotFoundException;
View
2  ...iguration/IndexPasswordRecoveryConfiguration.java → ...ion/index/IndexPasswordRecoveryConfiguration.java
@@ -1,4 +1,4 @@
-package com.baasbox.configuration;
+package com.baasbox.configuration.index;
import com.baasbox.dao.IndexDao;
import com.baasbox.exception.IndexNotFoundException;
View
4 ...baasbox/configuration/IndexPushConfiguration.java → ...x/configuration/index/IndexPushConfiguration.java
@@ -1,4 +1,4 @@
-package com.baasbox.configuration;
+package com.baasbox.configuration.index;
import com.baasbox.dao.IndexDao;
import com.baasbox.exception.IndexNotFoundException;
@@ -6,7 +6,7 @@
public class IndexPushConfiguration extends IndexDao {
private final static String indexName="_bb_push";
- protected IndexPushConfiguration() throws IndexNotFoundException {
+ public IndexPushConfiguration() throws IndexNotFoundException {
super(indexName);
// TODO Auto-generated constructor stub
}
View
2  .../configuration/IndexSocialLoginConfiguration.java → ...guration/index/IndexSocialLoginConfiguration.java
@@ -1,4 +1,4 @@
-package com.baasbox.configuration;
+package com.baasbox.configuration.index;
import com.baasbox.dao.IndexDao;
import com.baasbox.exception.IndexNotFoundException;
View
2  app/com/baasbox/controllers/Admin.java
@@ -540,6 +540,8 @@ public static Result setConfiguration(String section, String subSection, String
}
} catch (ConfigurationException e) {
return badRequest(e.getMessage());
+ }catch (IllegalStateException e) {
+ return badRequest("This configuration value is not editable");
}
return ok();
}
View
6 app/com/baasbox/db/DbHelper.java
@@ -375,7 +375,7 @@ public static void populateDB(ODatabaseRecordTx db) throws IOException{
dbg.command(new OCommandSQL(line.replace(';', ' '))).execute();
}
}
- Internal.DB_VERSION.setValue(BBConfiguration.configuration.getString(IBBConfigurationKeys.API_VERSION));
+ Internal.DB_VERSION._setValue(BBConfiguration.configuration.getString(IBBConfigurationKeys.API_VERSION));
String uniqueId="";
try{
UUID u = new UUID();
@@ -384,7 +384,7 @@ public static void populateDB(ODatabaseRecordTx db) throws IOException{
java.util.UUID u = java.util.UUID.randomUUID();
uniqueId=new String(Base64.encodeBase64(u.toString().getBytes()));
}
- Internal.INSTALLATION_ID.setValue(uniqueId);
+ Internal.INSTALLATION_ID._setValue(uniqueId);
Logger.info("Unique installation id is: " + uniqueId);
Logger.info("...done");
}
@@ -544,7 +544,7 @@ public static void evolveDB(ODatabaseRecordTx db) {
if (!fromVersion.equalsIgnoreCase(BBConfiguration.getApiVersion())){
Logger.info("...imported DB needs evolutions!...");
Evolutions.performEvolutions(db, fromVersion);
- Internal.DB_VERSION.setValue(BBConfiguration.getApiVersion());
+ Internal.DB_VERSION._setValue(BBConfiguration.getApiVersion());
Logger.info("DB version is now " + BBConfiguration.getApiVersion());
}//end of evolutions
}
View
2  app/com/baasbox/db/Evolution_0_7_0.java
@@ -93,7 +93,7 @@ private void edgeAndClassOptimization(ODatabaseRecordTx db) {
private void updateDBVersion(){
Logger.info("changing db level version to " + version);
- Internal.DB_VERSION.setValue(version);
+ Internal.DB_VERSION._setValue(version);
}
View
0  ...s/actions/filters/accesslog/AccessLogFilter.scala → app/com/baasbox/filters/LoggingFilter.scala
File renamed without changes
View
5 conf/application.conf
@@ -87,5 +87,10 @@ baasbox.startup.dumpdb=false
#enable/disable the access log
baasbox.server.accesslog=true
+#Example on how to override some settings. These values cannot be modified by the admin at runtime
+#baasbox.settings.Application.application.name.value="overridden app name"
+#baasbox.settings.Application.application.name.visible=false
+#baasbox.settings.Application.session_tokens.timeout.value=10
+#baasbox.settings.Application.session_tokens.timeout.visible=true
View
13 public/console/bbjs/baasboxgui.js
@@ -1607,7 +1607,8 @@ function setupTables(){
},
{"mData": "key", "mRender": function ( data, type, full ) {
- return getActionButton("edit","setting",data);
+ if (full.editable) return getActionButton("edit","setting",data);
+ else return "";
}
}],
@@ -1626,7 +1627,8 @@ function setupTables(){
}
},
{"mData": "key", "mRender": function ( data, type, full ) {
- return getActionButton("edit","setting",data);
+ if (full.editable) return getActionButton("edit","setting",data);
+ else return "";
}
}],
@@ -1645,7 +1647,8 @@ function setupTables(){
}
},
{"mData": "key", "mRender": function ( data, type, full ) {
- return getActionButton("edit","setting",data);
+ if (full.editable) return getActionButton("edit","setting",data);
+ else return "";
}
}],
@@ -1664,8 +1667,8 @@ function setupTables(){
}
},
{"mData": "key", "mRender": function ( data, type, full ) {
- return getActionButton("edit","setting",data);
- }
+ if (full.editable) return getActionButton("edit","setting",data);
+ else return ""; }
}],
"bRetrieve": true,
View
137 test/OverrideSettingsTest.java
@@ -0,0 +1,137 @@
+/*
+ Copyright 2012-2013
+ Claudio Tesoriero - c.tesoriero-at-baasbox.com
+
+ 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.
+*/
+
+// @author: Marco Tibuzzi
+
+import static play.mvc.Http.Status.BAD_REQUEST;
+import static play.mvc.Http.Status.OK;
+import static play.test.Helpers.GET;
+import static play.test.Helpers.contentAsString;
+import static play.test.Helpers.fakeApplication;
+import static play.test.Helpers.routeAndCall;
+import static play.test.Helpers.running;
+import static play.test.Helpers.status;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.baasbox.configuration.Application;
+import com.baasbox.db.DbHelper;
+
+import play.mvc.Result;
+import play.test.FakeRequest;
+import core.AbstractAdminTest;
+import core.TestConfig;
+
+public class OverrideSettingsTest extends AbstractAdminTest
+{
+ @Override
+ public String getRouteAddress()
+ {
+ return "/admin/configuration/dump.json";
+ }
+
+ @Override
+ public String getMethod()
+ {
+ return GET;
+ }
+
+
+
+ @Test
+ public void test()
+ {
+ running
+ (
+ fakeApplication(),
+ new Runnable()
+ {
+ public void run()
+ {
+ //load settings
+ FakeRequest request = new FakeRequest(GET, getRouteAddress());
+ request = request.withHeader(TestConfig.KEY_APPCODE, TestConfig.VALUE_APPCODE);
+ request = request.withHeader(TestConfig.KEY_AUTH, TestConfig.AUTH_ADMIN_ENC);
+ Result result = routeAndCall(request);
+ assertRoute(result, "LoadConfigurationAsJSON", OK, "application.name\":\"BaasBox\",\"description\":\"The App name\",\"type\":\"String\",\"editable\":true,\"visible\":true,\"overridden\":false", true);
+
+ //override setting
+ Application.APPLICATION_NAME.override("blablabla");
+
+ //reload settings
+ request = new FakeRequest(GET, getRouteAddress());
+ request = request.withHeader(TestConfig.KEY_APPCODE, TestConfig.VALUE_APPCODE);
+ request = request.withHeader(TestConfig.KEY_AUTH, TestConfig.AUTH_ADMIN_ENC);
+ result = routeAndCall(request);
+ assertRoute(result, "LoadConfigurationAsJSON", OK,
+ "application.name\":\"blablabla\",\"description\":\"The App name\",\"type\":\"String\",\"editable\":false,\"visible\":true,\"overridden\":true", true);
+
+ //tries to edit the value
+ try{
+ Application.APPLICATION_NAME.setValue("baasbox");
+ Assert.fail("APPLICATION_NAME changed, but it is overridden");
+ }catch (java.lang.IllegalStateException e){
+ }catch (Throwable t){
+ Assert.fail(t.getMessage());
+ }
+
+ Application.APPLICATION_NAME.setVisible(false);
+ //reload settings
+ request = new FakeRequest(GET, getRouteAddress());
+ request = request.withHeader(TestConfig.KEY_APPCODE, TestConfig.VALUE_APPCODE);
+ request = request.withHeader(TestConfig.KEY_AUTH, TestConfig.AUTH_ADMIN_ENC);
+ result = routeAndCall(request);
+ assertRoute(result, "LoadConfigurationAsJSON", OK,
+ "application.name\":\"--HIDDEN--\",\"description\":\"The App name\",\"type\":\"String\",\"editable\":false,\"visible\":false,\"overridden\":true", true);
+
+ //get the hidden value
+ try{
+ DbHelper.open("1234567890", "admin", "admin");
+ String hiddenValue=(String)Application.APPLICATION_NAME.getValue();
+ Assert.assertTrue("application.name: expected 'blablabla', it is " + hiddenValue, hiddenValue.equals("blablabla"));
+ }catch (Exception e){
+ Assert.fail(e.getMessage());
+ }finally{
+ DbHelper.close(DbHelper.getConnection());
+ }
+
+ //get the real-not-overridden value
+ try{
+ DbHelper.open("1234567890", "admin", "admin");
+ String hiddenValue=(String)Application.APPLICATION_NAME._getValue();
+ Assert.assertTrue("application.name: expected 'BaasBox', it is " + hiddenValue, hiddenValue.equals("BaasBox"));
+ }catch (Exception e){
+ Assert.fail(e.getMessage());
+ }finally{
+ DbHelper.close(DbHelper.getConnection());
+ }
+ }
+ }
+ );
+ }
+
+
+
+
+
+ @Override
+ protected void assertContent(String s) {
+ // TODO Auto-generated method stub
+
+ }
+}
Please sign in to comment.
Something went wrong with that request. Please try again.