Server initialization logic.

This commit is contained in:
robin shine 2013-09-21 15:38:32 +08:00
parent 35450b7834
commit cae54c3288
46 changed files with 851 additions and 53 deletions

View File

@ -33,6 +33,11 @@ public abstract class AbstractListEditSupport implements EditSupport {
return null;
}
@Override
public int getPriorty() {
return 1;
}
protected abstract AbstractPolymorphicListPropertyEditContext newPolymorphicListEditContext(Serializable bean, String propertyName);
protected abstract AbstractTableListPropertyEditContext newTableListEditContext(Serializable bean, String propertyName);

View File

@ -28,6 +28,11 @@ public abstract class AbstractReflectionEditSupport implements EditSupport {
}
}
@Override
public int getPriorty() {
return 1;
}
protected abstract AbstractReflectionBeanEditContext newReflectionBeanEditContext(Serializable bean);
protected abstract AbstractReflectionPropertyEditContext newReflectionPropertyEditContext(Serializable bean, String propertyName);

View File

@ -1,6 +1,10 @@
package com.pmease.commons.editable;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import javax.inject.Inject;
@ -11,11 +15,19 @@ import com.pmease.commons.util.GeneralException;
@Singleton
public class DefaultEditSupportRegistry implements EditSupportRegistry {
private final Set<EditSupport> editSupports;
private final List<EditSupport> editSupports;
@Inject
public DefaultEditSupportRegistry(Set<EditSupport> editSupports) {
this.editSupports = editSupports;
this.editSupports = new ArrayList<EditSupport>(editSupports);
Collections.sort(this.editSupports, new Comparator<EditSupport>() {
@Override
public int compare(EditSupport editSupport1, EditSupport editSupport2) {
return editSupport2.getPriorty() - editSupport1.getPriorty();
}
});
}
@Override

View File

@ -11,4 +11,5 @@ public interface EditSupport {
PropertyEditContext getPropertyEditContext(Serializable bean, String propertyName);
int getPriorty();
}

View File

@ -155,7 +155,8 @@ public abstract class AbstractPluginModule extends AbstractModule implements Dep
protected <T> void contribute(Class<T> extensionPoint, Class<? extends T> extensionClass) {
Multibinder<T> pluginBinder = Multibinder.newSetBinder(binder(), extensionPoint);
pluginBinder.addBinding().to(extensionClass).in(Singleton.class);
pluginBinder.addBinding().to(extensionClass);
bind(extensionClass).in(Singleton.class);
}
protected <T> void contribute(Class<T> extensionPoint, T extension) {

View File

@ -52,7 +52,7 @@
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-guice</artifactId>
<version>${shiroVersion}</version>
</dependency>
</dependency>
</dependencies>
<repositories>
<repository>

View File

@ -26,6 +26,10 @@ public class InitStage implements Serializable, Cloneable {
return message;
}
public List<ManualConfig> getManualConfigs() {
return manualConfigs;
}
public synchronized void waitFor() {
if (!manualConfigs.isEmpty()) {
try {
@ -33,7 +37,6 @@ public class InitStage implements Serializable, Cloneable {
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
manualConfigs.clear();
}
}
@ -46,19 +49,37 @@ public class InitStage implements Serializable, Cloneable {
final ManualConfig lastConfig = clonedConfigs.remove(clonedConfigs.size()-1);
clonedConfigs.add(new ManualConfig(lastConfig.getSetting()) {
clonedConfigs.add(new ManualConfig(lastConfig.getMessage(), lastConfig.getSetting()) {
@Override
public Skippable getSkippable() {
return lastConfig.getSkippable();
final Skippable skippable = lastConfig.getSkippable();
if (skippable != null) {
return new Skippable() {
@Override
public void skip() {
skippable.skip();
synchronized (InitStage.this) {
message = "Please wait...";
InitStage.this.manualConfigs.clear();
InitStage.this.notify();
}
}
};
} else {
return null;
}
}
@Override
public void complete() {
lastConfig.complete();
synchronized (InitStage.this) {
InitStage.this.notify();
message = "Please wait...";
InitStage.this.manualConfigs.clear();
InitStage.this.notify();
}
}

View File

@ -5,12 +5,19 @@ import java.io.Serializable;
@SuppressWarnings("serial")
public abstract class ManualConfig implements Serializable {
private final String message;
private final Serializable setting;
public ManualConfig(Serializable setting) {
public ManualConfig(String message, Serializable setting) {
this.message = message;
this.setting = setting;
}
public String getMessage() {
return message;
}
public Serializable getSetting() {
return setting;
}

View File

@ -63,6 +63,11 @@
<artifactId>commons.editable</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.pmease</groupId>
<artifactId>commons.shiro</artifactId>
<version>1.0.30</version>
</dependency>
</dependencies>
<properties>
<moduleClass>com.pmease.commons.wicket.WicketModule</moduleClass>

View File

@ -0,0 +1,58 @@
package com.pmease.commons.wicket.component.wizard;
import org.apache.wicket.Component;
import com.pmease.commons.editable.EditContext;
import com.pmease.commons.util.init.ManualConfig;
import com.pmease.commons.wicket.editable.EditHelper;
@SuppressWarnings("serial")
public class ManualConfigStep implements WizardStep {
private ManualConfig config;
private EditContext editContext;
public ManualConfigStep(ManualConfig config) {
this.config = config;
editContext = EditHelper.getContext(config.getSetting());
}
@Override
public Component render(String componentId) {
return EditHelper.renderForEdit(editContext, componentId);
}
@Override
public Skippable getSkippable() {
if (config.getSkippable() != null) {
return new Skippable() {
@Override
public void skip() {
config.getSkippable().skip();
}
};
} else {
return null;
}
}
@Override
public boolean complete() {
editContext.validate();
if (editContext.hasError(true)) {
return false;
} else {
config.complete();
return true;
}
}
@Override
public String getMessage() {
return config.getMessage();
}
}

View File

@ -0,0 +1,5 @@
package com.pmease.commons.wicket.component.wizard;
public interface Skippable {
void skip();
}

View File

@ -0,0 +1,16 @@
<wicket:panel>
<div class="wizard panel panel-default">
<div wicket:id="title" class="panel-heading"></div>
<div class="panel-body">
<form wicket:id="form">
<div wicket:id="content" class="content"></div>
<div class="buttons">
<a wicket:id="previous" class="btn btn-default previous">Previous</a>
<a wicket:id="skip" class="btn btn-default skip">Skip</a>
<a wicket:id="next" class="btn btn-primary next">Next</a>
<a wicket:id="finish" class="btn btn-primary finish">Finish</a>
</div>
</form>
</div>
</div>
</wicket:panel>

View File

@ -0,0 +1,159 @@
/*
* Copyright PMEase Inc.,
* Date: 2008-8-4
* Time: <EFBFBD><EFBFBD><EFBFBD><EFBFBD>09:00:25
* All rights reserved.
*
* Revision: $Id$
*/
package com.pmease.commons.wicket.component.wizard;
import java.util.Arrays;
import java.util.List;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.head.CssHeaderItem;
import org.apache.wicket.markup.head.HeaderItem;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.SubmitLink;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.AbstractReadOnlyModel;
import org.apache.wicket.request.resource.CssResourceReference;
import com.google.common.base.Preconditions;
import com.pmease.commons.wicket.asset.bootstrap.BootstrapResourceReference;
@SuppressWarnings("serial")
public abstract class Wizard extends Panel {
private static final String STEP_CONTENT_ID = "content";
private List<? extends WizardStep> steps;
private int activeStepIndex;
public Wizard(String id, List<? extends WizardStep> steps) {
super(id);
Preconditions.checkArgument(steps != null && !steps.isEmpty());
this.steps = steps;
}
@Override
protected void onInitialize() {
super.onInitialize();
add(new Label("title", new AbstractReadOnlyModel<String>() {
@Override
public String getObject() {
String template = "Step %s of %s: %s";
return String.format(template, activeStepIndex+1, steps.size(), getActiveStep().getMessage());
}
}));
final Form<?> form = new Form<Void>("form");
form.add(getActiveStep().render(STEP_CONTENT_ID));
form.add(new Link<Void>("previous") {
@Override
public void onClick() {
activeStepIndex--;
form.replace(getActiveStep().render(STEP_CONTENT_ID));
}
@Override
protected void onConfigure() {
super.onConfigure();
setEnabled(activeStepIndex > 0);
}
@Override
protected void onComponentTag(ComponentTag tag) {
super.onComponentTag(tag);
if (activeStepIndex <= 0)
tag.append("class", "disabled", " ");
}
});
form.add(new Link<Void>("skip") {
@Override
public void onClick() {
getActiveStep().getSkippable().skip();
if (activeStepIndex == steps.size() - 1)
finished();
else
form.replace(getActiveStep().render(STEP_CONTENT_ID));
}
@Override
protected void onConfigure() {
super.onConfigure();
setVisible(getActiveStep().getSkippable() != null);
}
});
form.add(new SubmitLink("next") {
@Override
public void onSubmit() {
if (getActiveStep().complete()) {
activeStepIndex++;
form.replace(getActiveStep().render(STEP_CONTENT_ID));
}
}
@Override
protected void onConfigure() {
super.onConfigure();
setVisible(activeStepIndex < steps.size()-1);
}
});
form.add(new SubmitLink("finish") {
@Override
public void onSubmit() {
if (getActiveStep().complete()) {
finished();
}
}
@Override
protected void onConfigure() {
super.onConfigure();
setVisible(activeStepIndex == steps.size()-1);
}
});
add(form);
}
private WizardStep getActiveStep() {
return steps.get(activeStepIndex);
}
protected abstract void finished();
@Override
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
response.render(CssHeaderItem.forReference(new CssResourceReference(Wizard.class, "wizard.css") {
@Override
public Iterable<? extends HeaderItem> getDependencies() {
return Arrays.asList(JavaScriptHeaderItem.forReference(new BootstrapResourceReference()));
}
}));
}
}

View File

@ -0,0 +1,24 @@
/*
* Copyright PMEase Inc.,
* Date: 2008-8-4
* All rights reserved.
*
* Revision: $Id$
*/
package com.pmease.commons.wicket.component.wizard;
import java.io.Serializable;
import org.apache.wicket.Component;
public interface WizardStep extends Serializable {
Component render(String componentId);
String getMessage();
Skippable getSkippable();
boolean complete();
}

View File

@ -0,0 +1,16 @@
.wizard table.reflection td.name {
background: none;
font-weight: normal;
}
.wizard .panel-heading {
font-size: 16px;
}
.wizard .buttons {
margin: 0 auto;
}
.wizard .buttons span em {
font-style: normal;
}
.wizard .buttons .previous, .wizard .buttons .skip {
margin-right: 20px;
}

View File

@ -28,4 +28,9 @@ public class BooleanEditSupport implements EditSupport {
}
}
@Override
public int getPriorty() {
return 1;
}
}

View File

@ -4,7 +4,6 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior;
@ -155,9 +154,6 @@ public class PolymorphicListPropertyEditor extends Panel {
}.setDefaultFormProcessing(false));
if (!item.getModelObject().getValidationErrors(false).isEmpty())
item.add(AttributeModifier.append("class", "has-error"));
item.add(new ListView<ValidationError>("elementValidationErrors", item.getModelObject().getValidationErrors(false)) {
@Override

View File

@ -1,8 +1,10 @@
package com.pmease.commons.wicket.editable.list.table;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
@ -19,6 +21,7 @@ import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.LoadableDetachableModel;
import com.pmease.commons.editable.EditContext;
import com.pmease.commons.editable.EditableUtils;
import com.pmease.commons.editable.PropertyEditContext;
import com.pmease.commons.editable.ValidationError;
@ -138,7 +141,8 @@ public class TableListPropertyEditor extends Panel {
});
if (!elementPropertyContext.getValidationErrors(false).isEmpty())
Map<Serializable, EditContext> childContexts = elementPropertyContext.getChildContexts();
if ((childContexts == null || childContexts.isEmpty()) && !elementPropertyContext.getValidationErrors(false).isEmpty())
columnItem.add(AttributeModifier.append("class", "has-error"));
}

View File

@ -27,4 +27,9 @@ public class NumericEditSupport implements EditSupport {
}
}
@Override
public int getPriorty() {
return 1;
}
}

View File

@ -0,0 +1,72 @@
package com.pmease.commons.wicket.editable.password;
import java.io.Serializable;
import java.util.Map;
import org.apache.shiro.authc.credential.PasswordService;
import org.apache.wicket.markup.html.basic.Label;
import com.pmease.commons.editable.EditContext;
import com.pmease.commons.editable.PropertyEditContext;
import com.pmease.commons.loader.AppLoader;
@SuppressWarnings("serial")
public class ConfirmativePasswordPropertyEditContext extends PropertyEditContext {
private String password;
private String confirmedPassword;
public ConfirmativePasswordPropertyEditContext(Serializable bean, String propertyName) {
super(bean, propertyName);
}
@Override
public Object renderForEdit(Object renderParam) {
return new ConfirmativePasswordPropertyEditor((String) renderParam, this);
}
@Override
public Object renderForView(Object renderParam) {
if (getPropertyValue() != null)
return new Label((String) renderParam, "******");
else
return new Label((String) renderParam, "<i>Not Defined</i>").setEscapeModelStrings(false);
}
@Override
protected void doValidation() {
super.doValidation();
if (password == null)
error("Please specify the password.");
else if (confirmedPassword == null)
error("Please confirm the password.");
else if (!password.equals(confirmedPassword))
error("Password and its confirmation should be identical.");
else
setPropertyValue(AppLoader.getInstance(PasswordService.class).encryptPassword(password));
}
@Override
public Map<Serializable, EditContext> getChildContexts() {
return null;
}
public String getPassword() {
return password;
}
public String getConfirmedPassword() {
return confirmedPassword;
}
public void setPassword(String password) {
this.password = password;
}
public void setConfirmedPassword(String confirmedPassword) {
this.confirmedPassword = confirmedPassword;
}
}

View File

@ -0,0 +1,14 @@
<wicket:panel>
<div class="input-group bottom-spacing">
<input wicket:id="input" type="password" class="form-control" placeholder="Type password here">
<span class="input-group-addon required" title="This field is required">
<span class="glyphicon glyphicon-asterisk"></span>
</span>
</div>
<div class="input-group">
<input wicket:id="inputAgain" type="password" class="form-control" placeholder="Confirm password here">
<span class="input-group-addon required" title="This field is required">
<span class="glyphicon glyphicon-asterisk"></span>
</span>
</div>
</wicket:panel>

View File

@ -0,0 +1,58 @@
package com.pmease.commons.wicket.editable.password;
import org.apache.wicket.markup.html.form.PasswordTextField;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
@SuppressWarnings("serial")
public class ConfirmativePasswordPropertyEditor extends Panel {
private final ConfirmativePasswordPropertyEditContext editContext;
public ConfirmativePasswordPropertyEditor(String id, ConfirmativePasswordPropertyEditContext editContext) {
super(id);
this.editContext = editContext;
}
@Override
protected void onInitialize() {
super.onInitialize();
add(new PasswordTextField("input", new IModel<String>() {
@Override
public void detach() {
}
@Override
public String getObject() {
return editContext.getPassword();
}
@Override
public void setObject(String object) {
editContext.setPassword(object);
}
}).setResetPassword(true).setRequired(false));
add(new PasswordTextField("inputAgain", new IModel<String>() {
@Override
public void detach() {
}
@Override
public String getObject() {
return editContext.getConfirmedPassword();
}
@Override
public void setObject(String object) {
editContext.setConfirmedPassword(object);
}
}).setResetPassword(true).setRequired(false));
}
}

View File

@ -0,0 +1,42 @@
package com.pmease.commons.wicket.editable.password;
import java.io.Serializable;
import java.lang.reflect.Method;
import com.pmease.commons.editable.BeanEditContext;
import com.pmease.commons.editable.EditSupport;
import com.pmease.commons.editable.PropertyEditContext;
import com.pmease.commons.editable.annotation.Password;
import com.pmease.commons.util.BeanUtils;
public class PasswordEditSupport implements EditSupport {
@Override
public BeanEditContext getBeanEditContext(Serializable bean) {
return null;
}
@Override
public PropertyEditContext getPropertyEditContext(Serializable bean, String propertyName) {
Method propertyGetter = BeanUtils.getGetter(bean.getClass(), propertyName);
if (propertyGetter.getReturnType() == String.class) {
Password password = propertyGetter.getAnnotation(Password.class);
if (password != null) {
if (password.confirmative())
return new ConfirmativePasswordPropertyEditContext(bean, propertyName);
else
return new PasswordPropertyEditContext(bean, propertyName);
} else {
return null;
}
} else {
return null;
}
}
@Override
public int getPriorty() {
return 2;
}
}

View File

@ -0,0 +1,36 @@
package com.pmease.commons.wicket.editable.password;
import java.io.Serializable;
import java.util.Map;
import org.apache.wicket.markup.html.basic.Label;
import com.pmease.commons.editable.EditContext;
import com.pmease.commons.editable.PropertyEditContext;
@SuppressWarnings("serial")
public class PasswordPropertyEditContext extends PropertyEditContext {
public PasswordPropertyEditContext(Serializable bean, String propertyName) {
super(bean, propertyName);
}
@Override
public Object renderForEdit(Object renderParam) {
return new PasswordPropertyEditor((String) renderParam, this);
}
@Override
public Object renderForView(Object renderParam) {
if (getPropertyValue() != null)
return new Label((String) renderParam, "******");
else
return new Label((String) renderParam, "<i>Not Defined</i>").setEscapeModelStrings(false);
}
@Override
public Map<Serializable, EditContext> getChildContexts() {
return null;
}
}

View File

@ -0,0 +1,16 @@
<wicket:panel>
<div wicket:id="content"></div>
<wicket:fragment wicket:id="required">
<div class="input-group">
<input wicket:id="input" type="password" class="form-control">
<span class="input-group-addon required" title="This field is required">
<span class="glyphicon glyphicon-asterisk"></span>
</span>
</div>
</wicket:fragment>
<wicket:fragment wicket:id="notRequired">
<input wicket:id="input" type="text" class="form-control">
</wicket:fragment>
</wicket:panel>

View File

@ -0,0 +1,50 @@
package com.pmease.commons.wicket.editable.password;
import org.apache.wicket.markup.html.form.PasswordTextField;
import org.apache.wicket.markup.html.panel.Fragment;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.IModel;
@SuppressWarnings("serial")
public class PasswordPropertyEditor extends Panel {
private final PasswordPropertyEditContext editContext;
public PasswordPropertyEditor(String id, PasswordPropertyEditContext editContext) {
super(id);
this.editContext = editContext;
}
@Override
protected void onInitialize() {
super.onInitialize();
Fragment fragment;
if (editContext.isPropertyRequired()) {
fragment = new Fragment("content", "required", this);
} else {
fragment = new Fragment("content", "notRequired", this);
}
fragment.add(new PasswordTextField("input", new IModel<String>() {
@Override
public void detach() {
}
@Override
public String getObject() {
return (String) editContext.getPropertyValue();
}
@Override
public void setObject(String object) {
editContext.setPropertyValue(object);
}
}).setResetPassword(false).setRequired(false));
add(fragment);
}
}

View File

@ -13,4 +13,9 @@ public class PolymorphicEditSuport extends AbstractPolymorphicEditSupport {
return new PolymorphicPropertyEditContext(bean, propertyName);
}
@Override
public int getPriorty() {
return 1;
}
}

View File

@ -1,6 +1,8 @@
package com.pmease.commons.wicket.editable.reflection;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import org.apache.wicket.AttributeModifier;
import org.apache.wicket.Component;
@ -12,6 +14,7 @@ import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.model.LoadableDetachableModel;
import com.pmease.commons.editable.EditContext;
import com.pmease.commons.editable.EditableUtils;
import com.pmease.commons.editable.PropertyEditContext;
import com.pmease.commons.editable.ValidationError;
@ -87,7 +90,8 @@ public class ReflectionBeanEditor extends Panel {
});
if (!propertyContext.getValidationErrors(false).isEmpty())
Map<Serializable, EditContext> childContexts = propertyContext.getChildContexts();
if ((childContexts == null || childContexts.isEmpty()) && !propertyContext.getValidationErrors(false).isEmpty())
item.add(AttributeModifier.append("class", "has-error"));
}

View File

@ -25,4 +25,9 @@ public class StringEditSupport implements EditSupport {
}
}
@Override
public int getPriorty() {
return 1;
}
}

View File

@ -104,7 +104,7 @@ public class Gitop extends AbstractPlugin {
return AppLoader.getInstance(type);
}
public static <T> Set<T> getExtensions(Class<T> extensionPoint) {
public <T> Set<T> getExtensions(Class<T> extensionPoint) {
return AppLoader.getExtensions(extensionPoint);
}

View File

@ -29,8 +29,6 @@ public class GitopModule extends AbstractPluginModule {
bind(NamingStrategy.class).toInstance(new PrefixedNamingStrategy("G"));
bind(Gitop.class);
contribute(ModelProvider.class, new ModelProvider() {
@Override

View File

@ -61,7 +61,7 @@ public class DefaultConfigManager extends DefaultGenericDao<Config> implements C
@Sessional
@Override
public MailSetting getMailSetting() {
Config config = getConfig(Key.STORAGE);
Config config = getConfig(Key.MAIL);
if (config != null) {
MailSetting mailSetting = (MailSetting) config.getSetting();
return mailSetting;
@ -73,10 +73,10 @@ public class DefaultConfigManager extends DefaultGenericDao<Config> implements C
@Transactional
@Override
public void saveMailSetting(MailSetting mailSetting) {
Config config = getConfig(Key.STORAGE);
Config config = getConfig(Key.MAIL);
if (config == null) {
config = new Config();
config.setKey(Key.STORAGE);
config.setKey(Key.MAIL);
}
config.setSetting(mailSetting);
save(config);

View File

@ -43,7 +43,7 @@ public class DefaultDataManager implements DataManager, Serializable {
List<ManualConfig> manualConfigs = new ArrayList<ManualConfig>();
User rootUser = userManager.find(null, new Order[]{Order.asc("id")});
if (rootUser == null) {
manualConfigs.add(new ManualConfig(new User()) {
manualConfigs.add(new ManualConfig("Create Administator Account", new User()) {
@Override
public Skippable getSkippable() {
@ -60,7 +60,7 @@ public class DefaultDataManager implements DataManager, Serializable {
Config storageConfig = configManager.getConfig(Key.STORAGE);
if (storageConfig == null || storageConfig.getSetting() == null) {
manualConfigs.add(new ManualConfig(new StorageSetting()) {
manualConfigs.add(new ManualConfig("Specify Storage Setting", new StorageSetting()) {
@Override
public Skippable getSkippable() {
@ -77,7 +77,7 @@ public class DefaultDataManager implements DataManager, Serializable {
Config mailConfig = configManager.getConfig(Key.MAIL);
if (mailConfig == null) {
manualConfigs.add(new ManualConfig(new MailSetting()) {
manualConfigs.add(new ManualConfig("Specify Mail Setting", new MailSetting()) {
@Override
public Skippable getSkippable() {

View File

@ -3,9 +3,15 @@ package com.pmease.gitop.core.model;
import java.util.ArrayList;
import java.util.Collection;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.OneToMany;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
import com.pmease.commons.editable.annotation.Editable;
import com.pmease.commons.editable.annotation.Password;
import com.pmease.commons.shiro.AbstractUser;
import com.pmease.gitop.core.permission.object.ProtectedObject;
import com.pmease.gitop.core.permission.object.UserBelonging;
@ -22,8 +28,12 @@ import com.pmease.gitop.core.permission.object.UserBelonging;
*/
@SuppressWarnings("serial")
@Entity
@Editable
public class User extends AbstractUser implements ProtectedObject {
@Column(nullable=false)
private String email;
private String description;
@OneToMany(mappedBy="user")
@ -47,6 +57,32 @@ public class User extends AbstractUser implements ProtectedObject {
@OneToMany(mappedBy="reviewer")
private Collection<VoteInvitation> voteVitations = new ArrayList<VoteInvitation>();
@Editable
@NotEmpty
@Override
public String getName() {
return super.getName();
}
@Editable
@NotEmpty
@Email
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Editable(name="Password")
@Password(confirmative=true)
@Override
public String getPasswordHash() {
return super.getPasswordHash();
}
@Editable
public String getDescription() {
return description;
}

View File

@ -2,7 +2,12 @@ package com.pmease.gitop.core.setting;
import java.io.Serializable;
import org.hibernate.validator.constraints.NotEmpty;
import com.pmease.commons.editable.annotation.Editable;
@SuppressWarnings("serial")
@Editable
public class MailSetting implements Serializable {
private String smtpHost;
@ -15,6 +20,8 @@ public class MailSetting implements Serializable {
private String senderAddress;
@Editable
@NotEmpty
public String getSmtpHost() {
return smtpHost;
}
@ -23,6 +30,7 @@ public class MailSetting implements Serializable {
this.smtpHost = smtpHost;
}
@Editable
public int getSmtpPort() {
return smtpPort;
}
@ -31,6 +39,7 @@ public class MailSetting implements Serializable {
this.smtpPort = smtpPort;
}
@Editable
public String getSmtpUser() {
return smtpUser;
}
@ -39,6 +48,7 @@ public class MailSetting implements Serializable {
this.smtpUser = smtpUser;
}
@Editable
public String getSmtpPassword() {
return smtpPassword;
}
@ -47,6 +57,7 @@ public class MailSetting implements Serializable {
this.smtpPassword = smtpPassword;
}
@Editable
public String getSenderAddress() {
return senderAddress;
}

View File

@ -2,11 +2,18 @@ package com.pmease.gitop.core.setting;
import java.io.Serializable;
import org.hibernate.validator.constraints.NotEmpty;
import com.pmease.commons.editable.annotation.Editable;
@SuppressWarnings("serial")
@Editable
public class StorageSetting implements Serializable {
private String repoStorageDir;
@Editable
@NotEmpty
public String getRepoStorageDir() {
return repoStorageDir;
}

View File

@ -2,6 +2,7 @@
<html>
<head>
<title wicket:id="title"></title>
<meta wicket:id="refresh" http-equiv="refresh"/>
</head>
<body>
<wicket:child></wicket:child>

View File

@ -1,20 +1,29 @@
package com.pmease.gitop.web;
import java.util.Arrays;
import org.apache.wicket.RestartResponseAtInterceptPageException;
import org.apache.wicket.markup.ComponentTag;
import org.apache.wicket.markup.head.CssHeaderItem;
import org.apache.wicket.markup.head.HeaderItem;
import org.apache.wicket.markup.head.IHeaderResponse;
import org.apache.wicket.markup.head.JavaScriptHeaderItem;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.request.resource.CssResourceReference;
import org.apache.wicket.request.resource.JavaScriptResourceReference;
import com.pmease.commons.wicket.asset.CommonResourceReference;
import com.pmease.gitop.core.Gitop;
import com.pmease.gitop.web.asset.AssetLocator;
@SuppressWarnings("serial")
public abstract class BasePage extends WebPage {
public BasePage() {
if (!Gitop.getInstance().isReady() && getClass() != InitPage.class)
throw new RestartResponseAtInterceptPageException(InitPage.class);
if (!Gitop.getInstance().isReady() && getClass() != ServerInitPage.class)
throw new RestartResponseAtInterceptPageException(ServerInitPage.class);
}
@Override
@ -22,6 +31,22 @@ public abstract class BasePage extends WebPage {
super.onInitialize();
add(new Label("title", getTitle()));
add(new WebMarkupContainer("refresh") {
@Override
protected void onComponentTag(ComponentTag tag) {
super.onComponentTag(tag);
tag.put("content", getPageRefreshInterval());
}
@Override
protected void onConfigure() {
super.onConfigure();
setVisible(getPageRefreshInterval() != 0);
}
});
}
protected abstract String getTitle();
@ -30,7 +55,20 @@ public abstract class BasePage extends WebPage {
public void renderHead(IHeaderResponse response) {
super.renderHead(response);
response.render(JavaScriptHeaderItem.forReference(new CommonResourceReference()));
response.render(JavaScriptHeaderItem.forReference(new JavaScriptResourceReference(AssetLocator.class, "page.js") {
@SuppressWarnings("unchecked")
@Override
public Iterable<? extends HeaderItem> getDependencies() {
return Arrays.asList(
JavaScriptHeaderItem.forReference(new CommonResourceReference()),
CssHeaderItem.forReference(new CssResourceReference(AssetLocator.class, "page.css")));
}
}));
}
protected int getPageRefreshInterval() {
return 0;
}
}

View File

@ -1,3 +1,3 @@
<wicket:extend>
Welcome Home!
<h1>Welcome Home!</h1>
</wicket:extend>

View File

@ -1,3 +0,0 @@
<wicket:extend>
Init
</wicket:extend>

View File

@ -1,22 +0,0 @@
package com.pmease.gitop.web;
import org.apache.wicket.RestartResponseException;
import com.pmease.commons.util.init.InitStage;
import com.pmease.gitop.core.Gitop;
@SuppressWarnings("serial")
public class InitPage extends BasePage {
public InitPage() {
InitStage initStage = Gitop.getInstance().getInitStage();
if (initStage == null)
throw new RestartResponseException(HomePage.class);
}
@Override
protected String getTitle() {
return "Initialization";
}
}

View File

@ -0,0 +1,6 @@
<wicket:extend>
<div class="server-init">
<h1 wicket:id="message" class="message"></h1>
<div wicket:id="wizard"></div>
</div>
</wicket:extend>

View File

@ -0,0 +1,67 @@
package com.pmease.gitop.web;
import java.util.ArrayList;
import java.util.List;
import org.apache.wicket.RestartResponseException;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.markup.html.basic.Label;
import com.pmease.commons.util.init.InitStage;
import com.pmease.commons.util.init.ManualConfig;
import com.pmease.commons.wicket.component.wizard.ManualConfigStep;
import com.pmease.commons.wicket.component.wizard.Wizard;
import com.pmease.gitop.core.Gitop;
@SuppressWarnings("serial")
public class ServerInitPage extends BasePage {
private InitStage initStage;
public ServerInitPage() {
initStage = Gitop.getInstance().getInitStage();
if (initStage == null) {
continueToOriginalDestination();
throw new RestartResponseException(HomePage.class);
}
}
@Override
protected void onInitialize() {
super.onInitialize();
if (initStage != null) {
add(new Label("message", initStage.getMessage()));
if (!initStage.getManualConfigs().isEmpty()) {
List<ManualConfigStep> configSteps = new ArrayList<ManualConfigStep>();
for (ManualConfig each: initStage.getManualConfigs())
configSteps.add(new ManualConfigStep(each));
add(new Wizard("wizard", configSteps) {
@Override
protected void finished() {
setResponsePage(ServerInitPage.class);
}
});
} else {
add(new WebMarkupContainer("wizard").setVisible(false));
}
}
}
@Override
protected String getTitle() {
return "Server Initialization";
}
@Override
protected int getPageRefreshInterval() {
if (initStage.getManualConfigs().isEmpty())
return 1;
else
return 0;
}
}

View File

@ -12,6 +12,9 @@ public class WicketConfig extends AbstractWicketConfig {
@Override
protected void init() {
super.init();
mountPage("/", HomePage.class);
mountPage("/init", ServerInitPage.class);
}
@Override

View File

@ -0,0 +1,9 @@
.server-init {
text-align: center;
width: 50%;
margin: 0 auto;
}
.server-init .message {
margin: 40px;
}