/** * Copyright 2012 Universitat Pompeu Fabra. * * 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. * * */ package org.onexus.ui.api.pages.resource; import org.apache.wicket.ajax.AjaxRequestTarget; import org.apache.wicket.ajax.markup.html.AjaxLink; import org.apache.wicket.behavior.AttributeAppender; import org.apache.wicket.markup.html.WebMarkupContainer; import org.apache.wicket.markup.html.basic.Label; import org.apache.wicket.markup.html.link.BookmarkablePageLink; import org.apache.wicket.markup.html.link.ExternalLink; import org.apache.wicket.markup.html.link.Link; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.model.AbstractWrapModel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.wicket.util.string.Strings; import org.onexus.resource.api.ORI; import org.onexus.resource.api.Resource; import org.onexus.ui.api.events.AjaxUpdateOnEvent; import org.onexus.ui.api.events.EventResourceSelect; import org.onexus.ui.api.viewers.EmptyPanelViewerCreator; import org.onexus.ui.api.viewers.IViewerCreator; import org.onexus.ui.api.viewers.IViewersManager; import javax.inject.Inject; import javax.inject.Named; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.regex.Pattern; public class ResourcesPage extends BaseResourcePage { public static final String PARAMETER_RESOURCE = "ori"; @Inject private IViewersManager viewersManager; public ResourcesPage(PageParameters parameters) { super(new ResourceModel(parameters.get(PARAMETER_RESOURCE).toOptionalString())); // Sync project add(new ToolProjectSync("projectSync")); // Update project add(new ToolProjectUpdate("projectUpdate")); // Copy resource URI add(new ToolCopyUri("copyURI", getModel())); // Resource URI breadcrumb add(new ToolOriBreadCrumb("oriBreadCrumb", getModel())); // Tabs add(new ViewerTabs("tabs", getModel())); } public class ToolProjectSync extends Link<Resource> { public ToolProjectSync(String id) { super(id); } @Override public void onClick() { Resource resource = ResourcesPage.this.getModelObject(); if (resource != null) { ORI resourceUri = resource.getORI(); getResourceManager().syncProject(resourceUri.getProjectUrl()); Resource newVersion = getResourceManager().load(Resource.class, resourceUri); if (newVersion == null) { resourceUri = resourceUri.getParent(); newVersion = getResourceManager().load(Resource.class, resourceUri); if (newVersion == null) { resourceUri = new ORI(resourceUri.getProjectUrl(), null); } } PageParameters parameters = new PageParameters(); parameters.set(ResourcesPage.PARAMETER_RESOURCE, resourceUri); setResponsePage(ResourcesPage.class, parameters); } } @Override public boolean isVisible() { return ResourcesPage.this.getModelObject() != null; } } public class ToolProjectUpdate extends Link<Resource> { public ToolProjectUpdate(String id) { super(id); } @Override public void onClick() { Resource resource = ResourcesPage.this.getModelObject(); if (resource != null) { ORI resourceUri = resource.getORI(); getResourceManager().updateProject(resourceUri.getProjectUrl()); Resource newVersion = getResourceManager().load(Resource.class, resourceUri); if (newVersion == null) { resourceUri = resourceUri.getParent(); newVersion = getResourceManager().load(Resource.class, resourceUri); if (newVersion == null) { resourceUri = new ORI(resourceUri.getProjectUrl(), null); } } PageParameters parameters = new PageParameters(); parameters.set(ResourcesPage.PARAMETER_RESOURCE, resourceUri); setResponsePage(ResourcesPage.class, parameters); } } @Override public boolean isVisible() { return ResourcesPage.this.getModelObject() != null; } } public static class ToolCopyUri extends ExternalLink { public ToolCopyUri(String id, IModel<Resource> resourceModel) { super(id, new PropertyModel<String>(resourceModel, "ORI")); add(new AjaxUpdateOnEvent(EventResourceSelect.EVENT)); } @Override public boolean isVisible() { return getDefaultModelObject() != null; } } public static class ToolOriBreadCrumb extends WebMarkupContainer { public ToolOriBreadCrumb(String id, IModel<Resource> resource) { super(id, resource); add(new AjaxUpdateOnEvent(EventResourceSelect.EVENT)); // Add list items add(new ListView<String>("ori", new BreadCrumbItemsModel(resource)) { private transient List<String> links; @Override protected void onBeforeRender() { BreadCrumbItemsModel model = (BreadCrumbItemsModel) getModel(); List<String> oriItems = model.getObject(); if (oriItems == null) { links = Collections.EMPTY_LIST; } links = new ArrayList<String>(oriItems.size()); Resource resource = model.getWrappedModel().getObject(); String projectUri = resource == null ? null : resource.getORI().getProjectUrl().toString(); links.add(projectUri); for (int i = 1; i < oriItems.size(); i++) { StringBuilder link = new StringBuilder(); link.append(projectUri).append("?"); link.append(oriItems.get(1)); for (int t = 2; t <= i; t++) { link.append(ORI.SEPARATOR); link.append(oriItems.get(t)); } links.add(link.toString()); } super.onBeforeRender(); } @Override protected void populateItem(ListItem<String> item) { // Link PageParameters parameters = new PageParameters(); String resourceUri = links.get(item.getIndex()); parameters.set(ResourcesPage.PARAMETER_RESOURCE, resourceUri); Link<String> link = new BookmarkablePageLink<String>("link", ResourcesPage.class, parameters); link.setEnabled(resourceUri != null); // Label link.add(new Label("name", item.getModelObject())); // Divider boolean showDivider = !(getModelObject().size() - 1 == item.getIndex()); Label divider = new Label("divider", item.getIndex() == 0 ? "?" : "/"); item.add(divider.setVisible(showDivider)); item.add(link); } }); } @Override public boolean isVisible() { return getDefaultModelObject() != null; } } public class ViewerTabs extends WebMarkupContainer { public ViewerTabs(String id, final IModel<Resource> resourceModel) { super(id); final IModel<Integer> currentViewer = new Model<Integer>(0); final ViewerCreatorsModel viewerCreators = new ViewerCreatorsModel(resourceModel); add(new AjaxUpdateOnEvent(EventResourceSelect.EVENT)); add(new ListView<IViewerCreator>("tab", viewerCreators) { @Override protected void populateItem(ListItem<IViewerCreator> item) { AjaxLink<Integer> link = new AjaxLink<Integer>("link", Model.of(item.getIndex())) { @Override public void onClick(AjaxRequestTarget target) { // Update selected tab Integer pos = getModelObject(); currentViewer.setObject(pos); // Update main panel IViewerCreator viewerCreator = viewerCreators.getViewerCreatorAt(pos); ResourcesPage.this.addOrReplace(viewerCreators.getViewerCreatorAt(pos).getPanel("main", resourceModel).setOutputMarkupId(true)); // Refresh using AJAX target.add(ResourcesPage.this.get("main")); target.add(ViewerTabs.this); } }; link.add(new Label("label", item.getModelObject().getTitle())); item.add(link); if (item.getIndex() == currentViewer.getObject()) { item.add(new AttributeAppender("class", "active")); } } }); ResourcesPage.this.add(viewerCreators.getViewerCreatorAt(0).getPanel("main", resourceModel).setOutputMarkupId(true)); } } private class ViewerCreatorsModel extends AbstractWrapModel<List<IViewerCreator>> { private IModel<Resource> resourceModel; private ViewerCreatorsModel(IModel<Resource> resourceModel) { this.resourceModel = resourceModel; } @Override public List<IViewerCreator> getObject() { Resource resource = resourceModel.getObject(); if (resource == null) { return Collections.EMPTY_LIST; } return viewersManager.getViewerCreators(resource); } @Override public IModel<?> getWrappedModel() { return resourceModel; } public IViewerCreator getViewerCreatorAt(int pos) { List<IViewerCreator> viewerCreators = getObject(); if (viewerCreators == null || viewerCreators.isEmpty()) { return new EmptyPanelViewerCreator(); } if (viewerCreators.size() <= pos) { return viewerCreators.get(0); } return viewerCreators.get(pos); } } private static class BreadCrumbItemsModel extends AbstractWrapModel<List<String>> { private IModel<Resource> resource; private ORI lastResourceUri; private transient List<String> object; private BreadCrumbItemsModel(IModel<Resource> resource) { super(); this.resource = resource; } @Override public List<String> getObject() { if (resource.getObject() == null) { return Collections.EMPTY_LIST; } if (!resource.getObject().getORI().equals(lastResourceUri)) { this.object = null; } if (object == null) { Resource resource = this.resource.getObject(); lastResourceUri = resource.getORI(); if (resource == null || resource.getORI() == null) { return Collections.EMPTY_LIST; } ORI ori = resource.getORI(); object = new ArrayList<String>(); ORI resourceOri = resource.getORI(); object.add(resourceOri.getProjectUrl()); if (!Strings.isEmpty(ori.getPath())) { // Remove the first separator String path = resourceOri.getPath().substring(1); object.addAll(Arrays.asList(path.split(Pattern.quote(String.valueOf(ORI.SEPARATOR))))); } } return object; } @Override public void detach() { this.object = null; } @Override public IModel<Resource> getWrappedModel() { return resource; } } }