Coverage Report - org.trails.component.EditCollection
 
Classes in this File Line Coverage Branch Coverage Complexity
EditCollection
79% 
92% 
0
 
 1  
 /*
 2  
  * Copyright 2004 Chris Nelson
 3  
  *
 4  
  * Licensed under the Apache License, Version 2.0 (the "License");
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
 7  
  * Unless required by applicable law or agreed to in writing,
 8  
  * software distributed under the License is distributed on an "AS IS" BASIS,
 9  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 10  
  * See the License for the specific language governing permissions and limitations under the License.
 11  
  */
 12  
 package org.trails.component;
 13  
 
 14  
 import java.util.ArrayList;
 15  
 import java.util.Collection;
 16  
 import java.util.Iterator;
 17  
 import java.util.List;
 18  
 
 19  
 import ognl.Ognl;
 20  
 import ognl.OgnlException;
 21  
 import org.apache.commons.lang.builder.EqualsBuilder;
 22  
 import org.apache.commons.lang.builder.HashCodeBuilder;
 23  
 import org.apache.commons.logging.Log;
 24  
 import org.apache.commons.logging.LogFactory;
 25  
 import org.apache.tapestry.IAsset;
 26  
 import org.apache.tapestry.IPage;
 27  
 import org.apache.tapestry.IRequestCycle;
 28  
 import org.apache.tapestry.annotations.Asset;
 29  
 import org.apache.tapestry.annotations.InjectObject;
 30  
 import org.apache.tapestry.annotations.InjectState;
 31  
 import org.apache.tapestry.annotations.Parameter;
 32  
 import org.apache.tapestry.contrib.palette.SortMode;
 33  
 import org.apache.tapestry.form.IPropertySelectionModel;
 34  
 import org.trails.TrailsRuntimeException;
 35  
 import org.trails.callback.CallbackStack;
 36  
 import org.trails.callback.CollectionCallback;
 37  
 import org.trails.callback.EditCallback;
 38  
 import org.trails.descriptor.CollectionDescriptor;
 39  
 import org.trails.descriptor.DescriptorService;
 40  
 import org.trails.descriptor.IClassDescriptor;
 41  
 import org.trails.descriptor.IPropertyDescriptor;
 42  
 import org.trails.page.EditPage;
 43  
 import org.trails.page.PageResolver;
 44  
 import org.trails.page.TrailsPage.PageType;
 45  
 import org.trails.persistence.PersistenceService;
 46  
 
 47  
 
 48  
 /**
 49  
  * This component produces a editor for a ManyToOne or ManyToMany collection.
 50  
  * It allows a user to edit a collection property
 51  
  *
 52  
  * @author Chris Nelson
 53  
  */
 54  17
 public abstract class EditCollection extends TrailsComponent
 55  
 {
 56  
 
 57  1
         protected static final Log LOG = LogFactory.getLog(EditCollection.class);
 58  
 
 59  
         @InjectState("callbackStack")
 60  
         public abstract CallbackStack getCallbackStack();
 61  
 
 62  
         public abstract void setCallbackStack(CallbackStack stack);
 63  
 
 64  
         @Parameter(required = true)
 65  
         public abstract Collection getCollection();
 66  
 
 67  
         public abstract void setCollection(Collection Collection);
 68  
 
 69  
         /**
 70  
          * The object which owns the collection being edited
 71  
          */
 72  
         @Parameter(required = false, defaultValue = "page.model")
 73  
         public abstract Object getModel();
 74  
 
 75  
         public abstract void setModel(Object Model);
 76  
 
 77  
         /**
 78  
          * Ognl expression to invoke on the model to create a new child instance
 79  
          */
 80  
         @Parameter(required = false)
 81  
         public abstract String getCreateExpression();
 82  
 
 83  
         public abstract void setCreateExpression(String CreateExpression);
 84  
 
 85  
         /**
 86  
          * The CollectionDescriptor for the collection being edited
 87  
          */
 88  
         @Parameter(required = true)
 89  
         public abstract IPropertyDescriptor getPropertyDescriptor();
 90  
 
 91  
         public abstract void setPropertyDescriptor(IPropertyDescriptor PropertyDescriptor);
 92  
 
 93  
         public abstract Object getCurrentObject();
 94  
 
 95  
         public abstract void setCurrentObject(Object CurrentObject);
 96  
 
 97  
         @Parameter(required = false, defaultValue = "page.descriptorService")
 98  
         public abstract DescriptorService getDescriptorService();
 99  
 
 100  
         @Parameter(required = false, defaultValue = "page.persistenceService")
 101  
         public abstract PersistenceService getPersistenceService();
 102  
 
 103  
         @Parameter(required = false, defaultValue = "not(collectionDescriptor.childRelationship)")
 104  
         public abstract boolean getAddFromExisting();
 105  
 
 106  
         @Parameter(required = false, defaultValue = "true")
 107  
         public abstract boolean isAllowCreate();
 108  
 
 109  
         public abstract int getIndex();
 110  
 
 111  
         public abstract void setIndex(int index);
 112  
 
 113  
         @Asset("classpath:move_up.gif")
 114  
         public abstract IAsset getUpImage();
 115  
 
 116  
         @Asset("classpath:move_down.gif")
 117  
         public abstract IAsset getDownImage();
 118  
 
 119  8
         private List selected = new ArrayList();
 120  
 
 121  
 
 122  
         /**
 123  
          * (non-Javadoc)
 124  
          *
 125  
          * @see org.apache.tapestry.AbstractComponent#prepareForRender(org.apache.tapestry.IRequestCycle)
 126  
          */
 127  
         protected void prepareForRender(IRequestCycle arg0)
 128  
         {
 129  
                 // TODO Auto-generated method stub
 130  0
                 super.prepareForRender(arg0);
 131  0
                 buildSelectedList();
 132  0
         }
 133  
 
 134  
         void buildSelectedList()
 135  
         {
 136  2
                 if (getCollection() != null)
 137  
                 {
 138  1
                         selected = new ArrayList();
 139  4
                         for (Iterator iter = getCollection().iterator(); iter.hasNext();)
 140  
                         {
 141  2
                                 iter.next();
 142  2
                                 selected.add(new Boolean(false));
 143  
                         }
 144  
                 }
 145  2
         }
 146  
 
 147  
         public CollectionDescriptor getCollectionDescriptor()
 148  
         {
 149  9
                 return (CollectionDescriptor) getPropertyDescriptor();
 150  
         }
 151  
 
 152  
         @InjectObject("service:trails.core.PageResolver")
 153  
         public abstract PageResolver getPageResolver();
 154  
 
 155  
         public IPage edit(Object member)
 156  
         {
 157  2
                 CollectionCallback callback = new CollectionCallback(
 158  1
                         getPage().getRequestCycle().getPage().getPageName(),
 159  1
                         getModel(),
 160  1
                         getCollectionDescriptor());
 161  1
                 getCallbackStack().push(callback);
 162  2
                 EditPage editPage = (EditPage) getPageResolver().resolvePage(
 163  1
                         getPage().getRequestCycle(),
 164  1
                         Utils.checkForCGLIB(member.getClass()),
 165  1
                         PageType.Edit);
 166  
 
 167  1
                 editPage.setModel(member);
 168  1
                 return editPage;
 169  
         }
 170  
 
 171  
 
 172  
         public void showAddPage(IRequestCycle cycle)
 173  
         {
 174  1
                 getCallbackStack().push(buildCallback());
 175  
 
 176  2
                 EditPage editPage = (EditPage) getPageResolver().resolvePage(cycle,
 177  1
                         getCollectionDescriptor().getElementType(),
 178  1
                         PageType.Edit);
 179  
                 try
 180  
                 {
 181  
                         // we need to do some indirection to avoid a StaleLink
 182  2
                         EditCallback nextPage = new EditCallback(editPage.getPageName(),
 183  1
                                 buildNewMemberInstance());
 184  1
                         String currentEditPageName = getPage().getRequestCycle().getPage().getPageName();
 185  1
                         ((EditPage) cycle.getPage(currentEditPageName)).setNextPage(nextPage);
 186  1
                         nextPage.performCallback(cycle);
 187  
                         //editPage.setModel(getCollectionDescriptor().getElementType().newInstance());
 188  
 
 189  0
                 } catch (Exception ex)
 190  
                 {
 191  0
                         throw new TrailsRuntimeException(ex, getCollectionDescriptor().getElementType() );
 192  
                 }
 193  1
         }
 194  
 
 195  
         protected Object buildNewMemberInstance() throws InstantiationException, IllegalAccessException
 196  
         {
 197  
                 Object object;
 198  1
                 if (getCreateExpression() == null)
 199  
                 {
 200  0
                         object = getCollectionDescriptor().getElementType().newInstance();
 201  
                 } else
 202  
                 {
 203  
                         try
 204  
                         {
 205  1
                                 object = Ognl.getValue(getCreateExpression(), getModel());
 206  
                         }
 207  0
                         catch (OgnlException oe)
 208  
                         {
 209  0
                                 oe.printStackTrace();
 210  0
                                 return null;
 211  
                         }
 212  
                 }
 213  
 
 214  1
                 if (getCollectionDescriptor().getInverseProperty() != null && getCollectionDescriptor().isOneToMany())
 215  
                 {
 216  
                         try
 217  
                         {
 218  0
                                 Ognl.setValue(getCollectionDescriptor().getInverseProperty(), object, getModel());
 219  0
                         } catch (OgnlException e)
 220  
                         {
 221  0
                                 LOG.error(e.getMessage());
 222  
                         }
 223  
                 }
 224  
 
 225  1
                 return object;
 226  
         }
 227  
 
 228  
         CollectionCallback buildCallback()
 229  
         {
 230  2
                 CollectionCallback callback = new CollectionCallback(
 231  1
                         getPage().getRequestCycle().getPage().getPageName(), getModel(), getCollectionDescriptor());
 232  1
                 callback.setChildRelationship(getCollectionDescriptor().isChildRelationship());
 233  1
                 return callback;
 234  
         }
 235  
 
 236  
         /**
 237  
          * @param cycle
 238  
          */
 239  
         public void remove(IRequestCycle cycle)
 240  
         {
 241  1
                 int i = 0;
 242  
                 // TODO CN - This code stinks (I wrote it).  Isn't there a better way??
 243  1
                 ArrayList deleting = new ArrayList();
 244  4
                 for (Iterator iter = getCollection().iterator(); iter.hasNext();)
 245  
                 {
 246  
 
 247  2
                         Object element = (Object) iter.next();
 248  
 
 249  2
                         if (((Boolean) getSelected().get(i)).booleanValue())
 250  
                         {
 251  1
                                 deleting.add(element);
 252  
                         }
 253  2
                         i++;
 254  
                 }
 255  1
                 getCollection().removeAll(deleting);
 256  1
         }
 257  
 
 258  
         public List getSelectedList()
 259  
         {
 260  1
                 ArrayList selectedList = new ArrayList();
 261  1
                 selectedList.addAll(getCollection());
 262  1
                 return selectedList;
 263  
         }
 264  
 
 265  
         public void setSelectedList(List selected)
 266  
         {
 267  0
                 if (selected != null)
 268  
                 {
 269  0
                         getCollection().clear();
 270  0
                         getCollection().addAll(selected);
 271  
                 }
 272  0
         }
 273  
 
 274  
         /**
 275  
          * @return Returns the toBeDeleted.
 276  
          */
 277  
         public List getSelected()
 278  
         {
 279  10
                 return selected;
 280  
         }
 281  
 
 282  
         /**
 283  
          * @param toBeDeleted The toBeDeleted to set.
 284  
          */
 285  
         public void setSelected(List toBeDeleted)
 286  
         {
 287  2
                 this.selected = toBeDeleted;
 288  2
         }
 289  
 
 290  
 
 291  
         /**
 292  
          * (non-Javadoc)
 293  
          *
 294  
          * @see java.lang.Object#equals(java.lang.Object)
 295  
          */
 296  
         public boolean equals(Object obj)
 297  
         {
 298  
                 // TODO Auto-generated method stub
 299  0
                 return EqualsBuilder.reflectionEquals(this, obj);
 300  
         }
 301  
 
 302  
 
 303  
         /**
 304  
          * (non-Javadoc)
 305  
          *
 306  
          * @see java.lang.Object#hashCode()
 307  
          */
 308  
         public int hashCode()
 309  
         {
 310  0
                 return HashCodeBuilder.reflectionHashCode(this);
 311  
         }
 312  
 
 313  
         /**
 314  
          * @return
 315  
          */
 316  
         public String getSortMode()
 317  
         {
 318  1
                 return isList() ? SortMode.USER : SortMode.LABEL;
 319  
         }
 320  
 
 321  
         public boolean isList()
 322  
         {
 323  1
                 return getCollection() instanceof List;
 324  
         }
 325  
 
 326  
         /**
 327  
          * @return
 328  
          */
 329  
         public IPropertySelectionModel getSelectionModel()
 330  
         {
 331  1
                 IClassDescriptor elementDescriptor = getDescriptorService().getClassDescriptor(getCollectionDescriptor().getElementType());
 332  
                 // don't allow use to select from all here
 333  1
                 if (getCollectionDescriptor().isChildRelationship())
 334  
                 {
 335  1
                         return new IdentifierSelectionModel(getSelectedList(), elementDescriptor.getIdentifierDescriptor().getName());
 336  
                 } else
 337  
                 {
 338  
                         // but do here
 339  0
                         return new IdentifierSelectionModel(getPersistenceService().getAllInstances(getCollectionDescriptor().getElementType()),
 340  0
                                 elementDescriptor.getIdentifierDescriptor().getName());
 341  
                 }
 342  
         }
 343  
 
 344  
         /**
 345  
          * @param cycle
 346  
          */
 347  
         public void moveUp(IRequestCycle cycle)
 348  
         {
 349  1
                 List list = (List) getCollection();
 350  2
                 for (int i = 1; i < getSelected().size(); i++)
 351  
                 {
 352  1
                         if (((Boolean) getSelected().get(i)).booleanValue())
 353  
                         {
 354  1
                                 swap(list, i, i - 1);
 355  
                         }
 356  
                 }
 357  1
         }
 358  
 
 359  
         private void swap(List list, int fromIndex, int toIndex)
 360  
         {
 361  2
                 Object from = list.get(fromIndex);
 362  2
                 Object to = list.get(toIndex);
 363  2
                 list.set(fromIndex, to);
 364  2
                 list.set(toIndex, from);
 365  2
         }
 366  
 
 367  
         /**
 368  
          * @param cycle
 369  
          */
 370  
         public void moveDown(IRequestCycle cycle)
 371  
         {
 372  1
                 List list = (List) getCollection();
 373  2
                 for (int i = 0; i < getSelected().size() - 1; i++)
 374  
                 {
 375  1
                         if (((Boolean) getSelected().get(i)).booleanValue())
 376  
                         {
 377  1
                                 swap(list, i, i + 1);
 378  
                         }
 379  
                 }
 380  1
         }
 381  
 }