package fr.openwide.maven.artifact.notifier.web.application.project.form; import java.util.Collections; import org.apache.wicket.Component; import org.apache.wicket.RestartResponseException; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.form.AjaxButton; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.form.RequiredTextField; import org.apache.wicket.markup.html.form.UrlTextField; import org.apache.wicket.markup.html.link.AbstractLink; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.apache.wicket.model.ResourceModel; import org.apache.wicket.model.StringResourceModel; import org.apache.wicket.spring.injection.annot.SpringBean; import org.apache.wicket.validation.IValidatable; import org.apache.wicket.validation.IValidationError; import org.apache.wicket.validation.ValidationError; import org.apache.wicket.validation.validator.PatternValidator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import fr.openwide.core.spring.util.StringUtils; import fr.openwide.core.wicket.more.markup.html.feedback.FeedbackUtils; import fr.openwide.core.wicket.more.markup.html.form.FormPanelMode; import fr.openwide.core.wicket.more.markup.html.template.js.jquery.plugins.bootstrap.modal.component.AbstractAjaxModalPopupPanel; import fr.openwide.core.wicket.more.markup.html.template.js.jquery.plugins.bootstrap.modal.component.DelegatedMarkupPanel; import fr.openwide.core.wicket.more.model.BindingModel; import fr.openwide.core.wicket.more.model.GenericEntityModel; import fr.openwide.maven.artifact.notifier.core.business.project.model.Project; import fr.openwide.maven.artifact.notifier.core.business.project.service.IProjectService; import fr.openwide.maven.artifact.notifier.core.util.binding.Binding; import fr.openwide.maven.artifact.notifier.web.application.MavenArtifactNotifierSession; import fr.openwide.maven.artifact.notifier.web.application.common.behavior.AuthenticatedOnlyBehavior; import fr.openwide.maven.artifact.notifier.web.application.navigation.link.LinkFactory; import fr.openwide.maven.artifact.notifier.web.application.project.component.ProjectLicenseDropDownChoice; import fr.openwide.maven.artifact.notifier.web.application.url.model.ExternalLinkWrapperWrapModel; public class ProjectFormPopupPanel extends AbstractAjaxModalPopupPanel<Project> { private static final long serialVersionUID = 4914283916847151778L; private static final Logger LOGGER = LoggerFactory.getLogger(ProjectFormPopupPanel.class); @SpringBean private IProjectService projectService; private FormPanelMode mode; private Form<Project> form; public ProjectFormPopupPanel(String id, FormPanelMode mode) { this(id, new GenericEntityModel<Long, Project>(null), mode); } public ProjectFormPopupPanel(String id, IModel<Project> projectModel) { this(id, projectModel, FormPanelMode.EDIT); } public ProjectFormPopupPanel(String id, IModel<Project> projectModel, FormPanelMode mode) { super(id, projectModel); this.mode = mode; add(new AuthenticatedOnlyBehavior()); } @Override protected Component createHeader(String wicketId) { if (isAddMode()) { return new Label(wicketId, new ResourceModel("project.add")); } else { return new Label(wicketId, new StringResourceModel("project.edit", getModel())); } } @Override protected Component createBody(String wicketId) { DelegatedMarkupPanel body = new DelegatedMarkupPanel(wicketId, ProjectFormPopupPanel.class); form = new Form<Project>("form", getModel()); form.add( new RequiredTextField<String>("name", BindingModel.of(getModel(), Binding.project().name())) .setLabel(new ResourceModel("project.field.name")) .add(new ProjectNamePatternValidator()) .setEnabled(MavenArtifactNotifierSession.get().hasRoleAdmin()), new UrlTextField("websiteUrl", new ExternalLinkWrapperWrapModel(BindingModel.of(getModel(), Binding.project().additionalInformation().websiteUrl()))) .setLabel(new ResourceModel("project.field.websiteUrl")), new UrlTextField("issueTrackerUrl", new ExternalLinkWrapperWrapModel(BindingModel.of(getModel(), Binding.project().additionalInformation().issueTrackerUrl()))) .setLabel(new ResourceModel("project.field.issueTrackerUrl")), new UrlTextField("scmUrl", new ExternalLinkWrapperWrapModel(BindingModel.of(getModel(), Binding.project().additionalInformation().scmUrl()))) .setLabel(new ResourceModel("project.field.scmUrl")), new UrlTextField("changelogUrl", new ExternalLinkWrapperWrapModel(BindingModel.of(getModel(), Binding.project().additionalInformation().changelogUrl()))) .setLabel(new ResourceModel("project.field.changelogUrl")), new ProjectLicenseDropDownChoice("licenses", BindingModel.of(getModel(), Binding.project().additionalInformation().licenses())) .setLabel(new ResourceModel("project.field.licenses")) ); body.add(form); return body; } @Override protected Component createFooter(String wicketId) { DelegatedMarkupPanel footer = new DelegatedMarkupPanel(wicketId, ProjectFormPopupPanel.class); // Validate button AjaxButton validate = new AjaxButton("save", form) { private static final long serialVersionUID = 1L; @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form) { Project project = ProjectFormPopupPanel.this.getModelObject(); if (StringUtils.hasText(project.getName())) { try { Project duplicate = projectService.getByUri(StringUtils.urlize(project.getName())); if (isAddMode()) { if (duplicate == null) { projectService.create(project); getSession().success(getString("project.add.success")); closePopup(target); target.add(getPage()); } else { LOGGER.warn("A project with the same name already exists"); getSession().error(getString("project.add.notUnique")); } } else { if (duplicate == null || project.equals(duplicate)) { projectService.update(project); getSession().success(getString("project.edit.success")); closePopup(target); throw LinkFactory.get().getAssortedProjectPageLinkDescriptor(getPage().getPageClass(), ProjectFormPopupPanel.this.getModel()) .newRestartResponseException(); } else { LOGGER.warn("A project with the same name already exists"); getSession().error(getString("project.add.notUnique")); } } } catch (RestartResponseException e) { throw e; } catch (Exception e) { if (isAddMode()) { LOGGER.error("Error occured while adding the project", e); getSession().error(getString("project.add.error")); } else { LOGGER.error("Error occured while updating the project", e); getSession().error(getString("project.edit.error")); } } } FeedbackUtils.refreshFeedback(target, getPage()); } @Override protected void onError(AjaxRequestTarget target, Form<?> form) { FeedbackUtils.refreshFeedback(target, getPage()); } }; validate.add(new Label("validateLabel", new ResourceModel("common.action.save"))); footer.add(validate); // Cancel button AbstractLink cancel = new AbstractLink("cancel") { private static final long serialVersionUID = 1L; }; addCancelBehavior(cancel); footer.add(cancel); return footer; } protected boolean isEditMode() { return FormPanelMode.EDIT.equals(mode); } protected boolean isAddMode() { return FormPanelMode.ADD.equals(mode); } @Override protected void onShow(AjaxRequestTarget target) { super.onShow(target); if (isAddMode()) { getModel().setObject(new Project()); } } @Override protected IModel<String> getCssClassNamesModel() { return Model.of("modal-project-form"); } public class ProjectNamePatternValidator extends PatternValidator { private static final long serialVersionUID = 315971574858314679L; private static final String PROJECT_NAME_VALIDATION_PATTERN = ".{2,100}"; public ProjectNamePatternValidator() { super(PROJECT_NAME_VALIDATION_PATTERN); } @Override protected IValidationError decorate(IValidationError error, IValidatable<String> validatable) { ((ValidationError) error).setKeys(Collections.singletonList("project.field.name.malformed")); return error; } } }