001 package hirondelle.web4jtools.codegenerator.field; 002 003 import hirondelle.web4j.action.ActionTemplateListAndEdit; 004 import hirondelle.web4j.action.ResponsePage; 005 import hirondelle.web4j.database.DAOException; 006 import hirondelle.web4j.database.DuplicateException; 007 import hirondelle.web4j.model.Id; 008 import hirondelle.web4j.model.ModelCtorException; 009 import hirondelle.web4j.model.ModelFromRequest; 010 import hirondelle.web4j.request.RequestParameter; 011 import hirondelle.web4j.request.RequestParser; 012 import hirondelle.web4j.util.Util; 013 014 import java.util.ArrayList; 015 import java.util.Iterator; 016 import java.util.List; 017 import java.util.logging.Logger; 018 019 /** 020 * Edit the fields used by the feature. 021 * 022 * <P>The order of how items are added will be retained in generated code. 023 */ 024 public final class FieldAction extends ActionTemplateListAndEdit { 025 026 /** Constructor. */ 027 public FieldAction(RequestParser aRequestParser){ 028 super(FORWARD, REDIRECT_TO_LISTING, aRequestParser); 029 } 030 031 public static final RequestParameter ID = RequestParameter.withLengthCheck("Id"); 032 public static final RequestParameter NAME = RequestParameter.withLengthCheck("Name"); 033 public static final RequestParameter DESCRIPTION = RequestParameter.withLengthCheck("Description"); 034 public static final RequestParameter IS_REQUIRED = RequestParameter.withLengthCheck("IsRequired"); 035 public static final RequestParameter TYPE = RequestParameter.withLengthCheck("Type"); 036 public static final RequestParameter CONTROL_STYLE = RequestParameter.withLengthCheck("ControlStyle"); 037 public static final RequestParameter IS_PRIMARY_KEY = RequestParameter.withRegexCheck("IsPrimaryKey", "(true|false)"); 038 public static final RequestParameter MINIMUM = RequestParameter.withLengthCheck("Minimum"); 039 public static final RequestParameter MAXIMUM = RequestParameter.withLengthCheck("Maximum"); 040 public static final RequestParameter ERROR_MESSAGE = RequestParameter.withLengthCheck("ErrorMessage"); 041 public static final RequestParameter IS_HARD_VALIDATED_FOR_LENGTH = RequestParameter.withRegexCheck("IsHardValidatedForLength", "(true|false)"); 042 public static final RequestParameter HARD_VALIDATON_PATTERN = RequestParameter.withLengthCheck("HardValidationPattern"); 043 public static final RequestParameter CHECK_PATTERN = RequestParameter.withLengthCheck("CheckPattern"); 044 public static final RequestParameter CHECK_EMAIL = RequestParameter.withLengthCheck("CheckEmail"); 045 public static final RequestParameter CHECK_SPAM = RequestParameter.withLengthCheck("CheckSpam"); 046 public static final RequestParameter IS_ORDER_BY_FIELD = RequestParameter.withRegexCheck("IsOrderByField", "(true|false)"); 047 public static final RequestParameter IS_DESC_ORDER = RequestParameter.withRegexCheck("IsDescendingOrder", "(true|false)"); 048 public static final RequestParameter NUM_DECIMALS = RequestParameter.withLengthCheck("NumDecimals"); 049 public static final RequestParameter CODE_TABLE = RequestParameter.withLengthCheck("CodeTable"); 050 051 /** Key for storing fields in session scope. */ 052 public static final String FIELDS_KEY = "fields"; 053 054 /** List all Fields, in the same order as created. */ 055 protected void doList() throws DAOException { 056 addToRequest(ITEMS_FOR_LISTING, list()); 057 } 058 059 /** Ensure user input can build a {@link Field}. */ 060 protected void validateUserInput() { 061 try { 062 ModelFromRequest builder = new ModelFromRequest(getRequestParser()); 063 fField = builder.build( 064 Field.class, ID, NAME, DESCRIPTION, IS_REQUIRED, TYPE, CONTROL_STYLE, IS_PRIMARY_KEY, MINIMUM, 065 MAXIMUM, NUM_DECIMALS, ERROR_MESSAGE, IS_HARD_VALIDATED_FOR_LENGTH, HARD_VALIDATON_PATTERN, 066 CHECK_PATTERN, CHECK_EMAIL, CHECK_SPAM, IS_ORDER_BY_FIELD, IS_DESC_ORDER, CODE_TABLE 067 ); 068 } 069 catch (ModelCtorException ex){ 070 addError(ex); 071 } 072 } 073 074 /** Add a new {@link Field}. */ 075 protected void attemptAdd() throws DAOException { 076 try { 077 add(fField); 078 addMessage("_1_ added successfully.", fField.getName()); 079 } 080 catch(DuplicateException ex){ 081 addError("Field Name already taken. Please use another name. Must be unique."); 082 } 083 } 084 085 /** Fetch an existing {@link Field} in order to edit it. */ 086 protected void attemptFetchForChange() throws DAOException { 087 Field field = fetch(getIdParam(ID)); 088 if( field != null ){ 089 addToRequest(ITEM_FOR_EDIT, field); 090 } 091 } 092 093 /** Apply an edit to an existing {@link Field}. */ 094 protected void attemptChange() throws DAOException { 095 boolean success = change(fField); 096 if (success){ 097 addMessage("_1_ changed successfully.", fField.getName()); 098 } 099 else { 100 addError("No update occurred. Item deleted?"); 101 } 102 } 103 104 /** Ensure the {@link Field} of a given id does not exist. */ 105 protected void attemptDelete() throws DAOException { 106 Id id = getIdParam(ID); 107 fLogger.fine("Deleting with id " + id); 108 delete(id); 109 addMessage("Item deleted successfully."); 110 } 111 112 // PRIVATE // 113 private Field fField; 114 private static final ResponsePage FORWARD = new ResponsePage("Fields", "view.jsp", FieldAction.class); 115 private static final ResponsePage REDIRECT_TO_LISTING = new ResponsePage("FieldAction.do?Operation=List"); 116 private static final Logger fLogger = Util.getLogger(FieldAction.class); 117 118 private List<Field> list() { 119 List<Field> result = new ArrayList<Field>(); 120 Object object = getFromSession(FIELDS_KEY); 121 if ( object != null ) { 122 result = (List<Field>)object; 123 } 124 return result; 125 } 126 127 private Field fetch(Id aFieldId) { 128 Field result = null; 129 List<Field> fields = list(); 130 if ( fields == null ) { 131 addError("Cannot fetch item. No Fields found in session."); 132 } 133 else { 134 Integer id = Integer.valueOf(aFieldId.toString()); 135 if ( id > fields.size() -1) { 136 addError("Cannot find Field of index " + id); 137 } 138 else { 139 result = fields.get(id); 140 } 141 } 142 return result; 143 } 144 145 private void add(Field aField) throws DuplicateException { 146 if ( contains(aField.getName()) ) { 147 RuntimeException ex = new RuntimeException(); 148 throw new DuplicateException("That field name is already taken. Please select another name.", ex); 149 } 150 List<Field> list = list(); 151 list.add(aField); //adds to the end of the list 152 applyUpdate(list); 153 } 154 155 private void applyUpdate(List<Field> aList) { 156 fLogger.fine("Applying update to fields stored in session."); 157 addToSession(FIELDS_KEY, aList); 158 } 159 160 private boolean contains(String aFieldName){ 161 boolean result = false; 162 List<Field> fields = list(); 163 for(Field field : fields ){ 164 if ( field.getName().equalsIgnoreCase(aFieldName)) { 165 result = true; 166 break; 167 } 168 } 169 return result; 170 } 171 172 private void delete(Id aFieldId){ 173 Integer id = Integer.valueOf(aFieldId.toString()); 174 List<Field> fields = list(); 175 if ( fields == null ) { 176 addError("No Fields in session. Cannot delete item."); 177 } 178 if ( id > fields.size() - 1 ) { 179 addError("Cannot find item using index : " + id); 180 } 181 else { 182 fLogger.fine("Removing item using id " + id); 183 fields.remove(id.intValue()); //must use int, not Integer!!! overloaded with Object 184 applyUpdate(fields); 185 } 186 } 187 188 private boolean change(Field aReplacementField) throws DuplicateException { 189 boolean result = false; 190 Integer id = Integer.valueOf(aReplacementField.getId().toString()); 191 //replace it with aReplacementField 192 List<Field> fields = list(); 193 Iterator<Field> iter = fields.iterator(); 194 int index = 0; 195 while ( iter.hasNext() ) { 196 if ( id == index ){ 197 fields.set(index, aReplacementField); 198 result = true; 199 break; 200 } 201 ++index; 202 } 203 return result; 204 } 205 }