/******************************************************************************* * * Copyright (c) 2004-2010 Oracle Corporation. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * * Tom Huybrechts * * *******************************************************************************/ package hudson.model; import hudson.Extension; import hudson.Util; import hudson.model.Descriptor.FormException; import hudson.security.ACL; import hudson.security.Permission; import hudson.util.FormValidation; import hudson.views.MyViewsTabBar; import hudson.views.ViewsTabBar; import java.io.IOException; import java.text.ParseException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.ServletException; import net.sf.json.JSONObject; import org.kohsuke.stapler.DataBoundConstructor; import org.kohsuke.stapler.HttpRedirect; import org.kohsuke.stapler.HttpResponse; import org.kohsuke.stapler.QueryParameter; import org.kohsuke.stapler.StaplerRequest; import org.kohsuke.stapler.StaplerResponse; import org.springframework.security.access.AccessDeniedException; /** * A UserProperty that remembers user-private views. * * @author Tom Huybrechts */ public class MyViewsProperty extends UserProperty implements ViewGroup, Action { private static final Logger log = Logger.getLogger(MyViewsProperty.class.getName()); private String primaryViewName; /** * Always hold at least one view. */ private CopyOnWriteArrayList<View> views = new CopyOnWriteArrayList<View>(); @DataBoundConstructor public MyViewsProperty(String primaryViewName) { this.primaryViewName = primaryViewName; } private MyViewsProperty() { views.add(new AllView(Messages.Hudson_ViewName(), this)); primaryViewName = views.get(0).getViewName(); } public String getPrimaryViewName() { return primaryViewName; } public void setPrimaryViewName(String primaryViewName) { this.primaryViewName = primaryViewName; } public User getUser() { return user; } ///// ViewGroup methods ///// public String getUrl() { return user.getUrl() + "/my-views/"; } public void save() throws IOException { user.save(); } public Collection<View> getViews() { List<View> copy = new ArrayList<View>(views); Collections.sort(copy, View.SORTER); return copy; } public View getView(String name) { for (View v : views) { if (v.getViewName().equals(name)) { return v; } } return null; } public boolean canDelete(View view) { return views.size() > 1; // Cannot delete last view } public void deleteView(View view) throws IOException { if (views.size() <= 1) { throw new IllegalStateException("Cannot delete last view"); } views.remove(view); if (view.getViewName().equals(primaryViewName)) { primaryViewName = views.get(0).getViewName(); } save(); } public void onViewRenamed(View view, String oldName, String newName) { if (primaryViewName.equals(oldName)) { primaryViewName = newName; try { save(); } catch (IOException ex) { log.log(Level.SEVERE, "error while saving user " + user.getId(), ex); } } } public void addView(View view) throws IOException { views.add(view); save(); } public View getPrimaryView() { if (primaryViewName != null) { View view = getView(primaryViewName); if (view != null) { return view; } } return views.get(0); } public HttpResponse doIndex() { return new HttpRedirect("view/" + getPrimaryView().getViewName() + "/"); } public synchronized void doCreateView(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, ParseException, FormException { checkPermission(View.CREATE); addView(View.create(req, rsp, this)); } /** * Checks if a private view with the given name exists. An error is returned * if exists==true but the view does not exist. An error is also returned if * exists==false but the view does exist. * */ public FormValidation doViewExistsCheck(@QueryParameter String value, @QueryParameter boolean exists) { checkPermission(View.CREATE); String view = Util.fixEmpty(value); if (view == null) { return FormValidation.ok(); } if (exists) { return (getView(view) != null) ? FormValidation.ok() : FormValidation.error(Messages.MyViewsProperty_ViewExistsCheck_NotExist(view)); } else { return (getView(view) == null) ? FormValidation.ok() : FormValidation.error(Messages.MyViewsProperty_ViewExistsCheck_AlreadyExists(view)); } } public ACL getACL() { return user.getACL(); } public void checkPermission(Permission permission) throws AccessDeniedException { getACL().checkPermission(permission); } public boolean hasPermission(Permission permission) { return getACL().hasPermission(permission); } ///// Action methods ///// public String getDisplayName() { return Messages.MyViewsProperty_DisplayName(); } public String getIconFileName() { return "user.png"; } public String getUrlName() { return "my-views"; } @Extension public static class DescriptorImpl extends UserPropertyDescriptor { @Override public String getDisplayName() { return Messages.MyViewsProperty_DisplayName(); } @Override public UserProperty newInstance(User user) { return new MyViewsProperty(); } } @Override public UserProperty reconfigure(StaplerRequest req, JSONObject form) throws FormException { req.bindJSON(this, form); return this; } public Object readResolve() { if (views == null) // this shouldn't happen, but an error in 1.319 meant the last view could be deleted { views = new CopyOnWriteArrayList<View>(); } if (views.isEmpty()) // preserve the non-empty invariant { views.add(new AllView(Messages.Hudson_ViewName(), this)); } return this; } public ViewsTabBar getViewsTabBar() { return Hudson.getInstance().getViewsTabBar(); } public MyViewsTabBar getMyViewsTabBar() { return Hudson.getInstance().getMyViewsTabBar(); } @Extension public static class GlobalAction implements RootAction { public String getDisplayName() { return Messages.MyViewsProperty_GlobalAction_DisplayName(); } public String getIconFileName() { // do not show when not logged in if (User.current() == null) { return null; } return "user.png"; } public String getUrlName() { return "/me/my-views"; } } }