Coverage Report - org.kuali.student.core.statement.service.impl.StatementServiceImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
StatementServiceImpl
62%
299/477
39%
49/124
2.355
 
 1  
 /**
 2  
  * Copyright 2010 The Kuali Foundation Licensed under the
 3  
  * Educational Community License, Version 2.0 (the "License"); you may
 4  
  * not use this file except in compliance with the License. You may
 5  
  * obtain a copy of the License at
 6  
  *
 7  
  * http://www.osedu.org/licenses/ECL-2.0
 8  
  *
 9  
  * Unless required by applicable law or agreed to in writing,
 10  
  * software distributed under the License is distributed on an "AS IS"
 11  
  * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 12  
  * or implied. See the License for the specific language governing
 13  
  * permissions and limitations under the License.
 14  
  */
 15  
 
 16  
 package org.kuali.student.core.statement.service.impl;
 17  
 
 18  
 import java.util.ArrayList;
 19  
 import java.util.HashMap;
 20  
 import java.util.HashSet;
 21  
 import java.util.Iterator;
 22  
 import java.util.List;
 23  
 import java.util.Map;
 24  
 import java.util.Set;
 25  
 
 26  
 import javax.jws.WebService;
 27  
 
 28  
 import org.kuali.student.common.dictionary.dto.ObjectStructureDefinition;
 29  
 import org.kuali.student.common.dictionary.service.DictionaryService;
 30  
 import org.kuali.student.common.dto.StatusInfo;
 31  
 import org.kuali.student.common.exceptions.AlreadyExistsException;
 32  
 import org.kuali.student.common.exceptions.CircularReferenceException;
 33  
 import org.kuali.student.common.exceptions.DataValidationErrorException;
 34  
 import org.kuali.student.common.exceptions.DoesNotExistException;
 35  
 import org.kuali.student.common.exceptions.InvalidParameterException;
 36  
 import org.kuali.student.common.exceptions.MissingParameterException;
 37  
 import org.kuali.student.common.exceptions.OperationFailedException;
 38  
 import org.kuali.student.common.exceptions.PermissionDeniedException;
 39  
 import org.kuali.student.common.exceptions.VersionMismatchException;
 40  
 import org.kuali.student.common.search.dto.SearchCriteriaTypeInfo;
 41  
 import org.kuali.student.common.search.dto.SearchParam;
 42  
 import org.kuali.student.common.search.dto.SearchRequest;
 43  
 import org.kuali.student.common.search.dto.SearchResult;
 44  
 import org.kuali.student.common.search.dto.SearchResultRow;
 45  
 import org.kuali.student.common.search.dto.SearchResultTypeInfo;
 46  
 import org.kuali.student.common.search.dto.SearchTypeInfo;
 47  
 import org.kuali.student.common.search.service.SearchManager;
 48  
 import org.kuali.student.common.validation.dto.ValidationResultInfo;
 49  
 import org.kuali.student.common.validator.Validator;
 50  
 import org.kuali.student.common.validator.ValidatorFactory;
 51  
 import org.kuali.student.core.statement.dao.StatementDao;
 52  
 import org.kuali.student.core.statement.dto.NlUsageTypeInfo;
 53  
 import org.kuali.student.core.statement.dto.RefStatementRelationInfo;
 54  
 import org.kuali.student.core.statement.dto.RefStatementRelationTypeInfo;
 55  
 import org.kuali.student.core.statement.dto.ReqComponentInfo;
 56  
 import org.kuali.student.core.statement.dto.ReqComponentTypeInfo;
 57  
 import org.kuali.student.core.statement.dto.StatementInfo;
 58  
 import org.kuali.student.core.statement.dto.StatementTreeViewInfo;
 59  
 import org.kuali.student.core.statement.dto.StatementTypeInfo;
 60  
 import org.kuali.student.core.statement.entity.NlUsageType;
 61  
 import org.kuali.student.core.statement.entity.ObjectType;
 62  
 import org.kuali.student.core.statement.entity.RefStatementRelation;
 63  
 import org.kuali.student.core.statement.entity.RefStatementRelationAttribute;
 64  
 import org.kuali.student.core.statement.entity.RefStatementRelationType;
 65  
 import org.kuali.student.core.statement.entity.ReqComponent;
 66  
 import org.kuali.student.core.statement.entity.ReqComponentType;
 67  
 import org.kuali.student.core.statement.entity.Statement;
 68  
 import org.kuali.student.core.statement.entity.StatementType;
 69  
 import org.kuali.student.core.statement.naturallanguage.NaturalLanguageTranslator;
 70  
 import org.kuali.student.core.statement.naturallanguage.translators.ReqComponentTranslator;
 71  
 import org.kuali.student.core.statement.service.StatementService;
 72  
 import org.slf4j.Logger;
 73  
 import org.slf4j.LoggerFactory;
 74  
 import org.springframework.beans.BeanUtils;
 75  
 import org.springframework.transaction.annotation.Transactional;
 76  
 
 77  
 @WebService(endpointInterface = "org.kuali.student.core.statement.service.StatementService", serviceName = "StatementService", portName = "StatementService", targetNamespace = "http://student.kuali.org/wsdl/statement")
 78  4
 public class StatementServiceImpl implements StatementService {
 79  
 
 80  1
         private final static Logger logger = LoggerFactory.getLogger(ReqComponentTranslator.class);
 81  
 
 82  
         private static final String SEARCH_KEY_DEPENDENCY_ANALYSIS = "stmt.search.dependencyAnalysis";
 83  
 
 84  
         private StatementDao statementDao;
 85  
         private NaturalLanguageTranslator naturalLanguageTranslator;
 86  
     private SearchManager searchManager;
 87  
     private DictionaryService dictionaryServiceDelegate;
 88  
     private StatementAssembler statementAssembler;
 89  
     private ValidatorFactory validatorFactory;
 90  
     // private StatementTreeViewAssembler statementTreeViewAssembler;
 91  
 
 92  
         public void setStatementAssembler(StatementAssembler statementAssembler) {
 93  2
                 this.statementAssembler = statementAssembler;
 94  2
         }
 95  
 
 96  
         public SearchManager getSearchManager() {
 97  0
         return searchManager;
 98  
     }
 99  
 
 100  
     public void setSearchManager(final SearchManager searchManager) {
 101  2
         this.searchManager = searchManager;
 102  2
     }
 103  
 
 104  
     public DictionaryService getDictionaryServiceDelegate() {
 105  0
         return dictionaryServiceDelegate;
 106  
     }
 107  
 
 108  
     public void setDictionaryServiceDelegate(final DictionaryService dictionaryServiceDelegate) {
 109  2
             this.dictionaryServiceDelegate = dictionaryServiceDelegate;
 110  2
     }
 111  
 
 112  
     public StatementDao getStatementDao() {
 113  0
         return statementDao;
 114  
     }
 115  
 
 116  
     public void setStatementDao(final StatementDao statementDao) {
 117  2
                 this.statementDao = statementDao;
 118  2
         }
 119  
 
 120  
     public NaturalLanguageTranslator getNaturalLanguageTranslator() {
 121  0
         return naturalLanguageTranslator;
 122  
     }
 123  
 
 124  
         public void setNaturalLanguageTranslator(final NaturalLanguageTranslator translator) {
 125  2
                 this.naturalLanguageTranslator = translator;
 126  2
         }
 127  
 
 128  
     @Transactional(readOnly=true)
 129  
         public NlUsageTypeInfo getNlUsageType(final String nlUsageTypeKey)
 130  
                         throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 131  
 
 132  11
                 checkForNullOrEmptyParameter(nlUsageTypeKey, "nlUsageTypeKey");
 133  11
                 checkForEmptyParameter(nlUsageTypeKey, "nlUsageTypeKey");
 134  
 
 135  11
                 NlUsageType entity = this.statementDao.fetch(NlUsageType.class, nlUsageTypeKey);
 136  9
                 NlUsageTypeInfo info = StatementAssembler.toNlUsageTypeInfo(entity);
 137  9
                 return info;
 138  
         }
 139  
 
 140  
     @Transactional(readOnly=true)
 141  
         public List<NlUsageTypeInfo> getNlUsageTypes()
 142  
                         throws OperationFailedException {
 143  
 
 144  1
                 List<NlUsageType> entities = this.statementDao.find(NlUsageType.class);
 145  1
                 List<NlUsageTypeInfo> infos = StatementAssembler.toNlUsageTypeInfos(entities);
 146  1
                 return infos;
 147  
         }
 148  
 
 149  
     @Transactional(readOnly=true)
 150  
         public List<String> getRefObjectTypes() throws OperationFailedException {
 151  1
                 List<ObjectType> objectTypes = this.statementDao.find(ObjectType.class);
 152  1
                 List<String> ids = new ArrayList<String>();
 153  1
                 for(ObjectType objectType : objectTypes) {
 154  1
                         ids.add(objectType.getId());
 155  
                 }
 156  1
                 return ids;
 157  
         }
 158  
 
 159  
     @Transactional(readOnly=true)
 160  
         public List<String> getRefObjectSubTypes(final String objectTypeKey)
 161  
                         throws DoesNotExistException,
 162  
                         InvalidParameterException, MissingParameterException,
 163  
                         OperationFailedException {
 164  
 
 165  1
                 checkForNullOrEmptyParameter(objectTypeKey, "objectTypeKey");
 166  1
                 checkForEmptyParameter(objectTypeKey, "objectTypeKey");
 167  
 
 168  1
                 ObjectType objectType = this.statementDao.fetch(ObjectType.class, objectTypeKey);
 169  1
                 List<String> ids = StatementAssembler.toRefObjectSubTypeIds(objectType);
 170  1
                 return ids;
 171  
         }
 172  
 
 173  
     @Transactional(readOnly=true)
 174  
         public RefStatementRelationInfo getRefStatementRelation(final String refStatementRelationId)
 175  
                         throws DoesNotExistException, InvalidParameterException,
 176  
                         MissingParameterException, OperationFailedException {
 177  
 
 178  1
                 checkForNullOrEmptyParameter(refStatementRelationId, "refStatementRelationId");
 179  1
                 checkForEmptyParameter(refStatementRelationId, "refStatementRelationId");
 180  
 
 181  1
             RefStatementRelation entity = this.statementDao.fetch(RefStatementRelation.class, refStatementRelationId);
 182  1
             RefStatementRelationInfo dto = StatementAssembler.toRefStatementRelationInfo(entity);
 183  1
                 return dto;
 184  
         }
 185  
 
 186  
     @Transactional(readOnly=true)
 187  
         public List<RefStatementRelationInfo> getRefStatementRelationsByRef(final String refObjectTypeKey, final String refObjectId)
 188  
                         throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 189  0
         checkForNullOrEmptyParameter(refObjectTypeKey, "refObjectTypeKey");
 190  0
         checkForEmptyParameter(refObjectId, "refObjectId");
 191  
 
 192  0
         List<RefStatementRelation> references = this.statementDao.getRefStatementRelations(
 193  
                 refObjectTypeKey, refObjectId);
 194  0
         List<RefStatementRelationInfo> referenceInfos = null;
 195  0
         if (references != null) {
 196  0
             for (RefStatementRelation reference : references) {
 197  0
                 RefStatementRelationInfo dto = StatementAssembler.toRefStatementRelationInfo(reference);
 198  0
                 referenceInfos = (referenceInfos == null)? new ArrayList<RefStatementRelationInfo>(7) : referenceInfos;
 199  0
                 referenceInfos.add(dto);
 200  0
             }
 201  
         }
 202  0
         return referenceInfos;
 203  
         }
 204  
 
 205  
     @Transactional(readOnly=true)
 206  
         public List<RefStatementRelationInfo> getRefStatementRelationsByStatement(final String statementId)
 207  
                         throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 208  
 
 209  3
                 checkForNullOrEmptyParameter(statementId, "statementId");
 210  
 
 211  1
                 Statement statement = this.statementDao.fetch(Statement.class, statementId);
 212  1
                 List<RefStatementRelation> entities = statement.getRefStatementRelations();
 213  1
                 List<RefStatementRelationInfo> dtoList = StatementAssembler.toRefStatementRelationInfos(entities);
 214  1
                 return dtoList;
 215  
         }
 216  
 
 217  
         /**
 218  
          * <p>Translates and retrieves a requirement component for a specific
 219  
          * usuage type (context) into natural language.</p>
 220  
          *
 221  
          * <p>If <code>language</code> is null default language is used.</p>
 222  
          *
 223  
          * @param reqComponentId Requirement component to translate
 224  
          * @param nlUsageTypeKey Natural language usage type key (context)
 225  
          * @param language Translation language
 226  
      * @throws DoesNotExistException ReqComponent not found
 227  
      * @throws InvalidParameterException Invalid nlUsageTypeKey
 228  
      * @throws MissingParameterException Missing reqComponentId or nlUsageTypeKey
 229  
      * @throws OperationFailedException Unable to complete request
 230  
      * @throws VersionMismatchException The action was attempted on an out of date version.
 231  
          */
 232  
     @Transactional(readOnly=true)
 233  
         public String getNaturalLanguageForReqComponent(final String reqComponentId, final String nlUsageTypeKey, final String language)
 234  
                         throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 235  
 
 236  8
                 checkForNullOrEmptyParameter(reqComponentId, "reqComponentId");
 237  8
                 checkForNullOrEmptyParameter(nlUsageTypeKey, "nlUsageTypeKey");
 238  8
                 checkForEmptyParameter(language, "language");
 239  
 
 240  
                 // test usage type key exists
 241  8
                 getNlUsageType(nlUsageTypeKey);
 242  
 
 243  7
                 ReqComponent reqComponent = this.statementDao.fetch(ReqComponent.class, reqComponentId);
 244  7
                 String nl = this.naturalLanguageTranslator.translateReqComponent(reqComponent, nlUsageTypeKey, language);
 245  
 
 246  7
                 if(logger.isInfoEnabled()) {
 247  0
                         logger.info("reqComponentId="+reqComponentId);
 248  0
                         logger.info("nlUsageTypeKey="+nlUsageTypeKey);
 249  0
                         logger.info("language="+language);
 250  0
                         logger.info("ReqComponent translation="+nl);
 251  
                 }
 252  
 
 253  7
                 return nl;
 254  
         }
 255  
 
 256  
         /**
 257  
          * <p>Translates and retrieves a statement directly attached to a CLU
 258  
          * for a specific usuage type (context) into natural language.
 259  
          *
 260  
          * If <code>cluId</code> is null or empty then statement header is not
 261  
          * generated</p>
 262  
          *
 263  
          * <p>If <code>language</code> is null default language is used.</p>
 264  
          *
 265  
          * <p>An <code>StatementInfo</code> can either have a list of
 266  
          * <code>StatementInfo</code>s as children or a list of
 267  
          * <code>ReqComponentInfo</code>s but not both. This means that all leaf
 268  
          * nodes must be <code>ReqComponentInfo</code>s.</p>
 269  
          *
 270  
          * @param statementId Statement to translate
 271  
          * @param nlUsageTypeKey Natural language usage type key (context)
 272  
          * @param language Translation language
 273  
      * @throws DoesNotExistException Statement not found or Clu anchor not found in statement
 274  
      * @throws InvalidParameterException Invalid nlUsageTypeKey
 275  
      * @throws MissingParameterException Missing statementId or nlUsageTypeKey
 276  
      * @throws OperationFailedException Unable to complete request
 277  
      * @throws VersionMismatchException The action was attempted on an out of date version.
 278  
          */
 279  
     @Transactional(readOnly=true)
 280  
         public String getNaturalLanguageForStatement(final String statementId, final String nlUsageTypeKey, final String language)
 281  
                         throws DoesNotExistException, InvalidParameterException,
 282  
                         MissingParameterException, OperationFailedException {
 283  
 
 284  1
                 checkForNullOrEmptyParameter(statementId, "statementId");
 285  1
                 checkForNullOrEmptyParameter(nlUsageTypeKey, "nlUsageTypeKey");
 286  1
                 checkForEmptyParameter(language, "language");
 287  
 
 288  1
                 Statement statement = this.statementDao.fetch(Statement.class, statementId);
 289  1
                 String nl = this.naturalLanguageTranslator.translateStatement(statement, nlUsageTypeKey, language);
 290  
 
 291  1
                 if(logger.isInfoEnabled()) {
 292  0
                         logger.info("statementId="+statementId);
 293  0
                         logger.info("nlUsageTypeKey="+nlUsageTypeKey);
 294  0
                         logger.info("language="+language);
 295  0
                         logger.info("Statement translation="+nl);
 296  
                 }
 297  
 
 298  1
                 return nl;
 299  
         }
 300  
 
 301  
     @Transactional(readOnly=true)
 302  
     public String getNaturalLanguageForRefStatementRelation(final String refStatementRelationId, final String nlUsageTypeKey, final String language) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 303  1
                 checkForNullOrEmptyParameter(refStatementRelationId, "refStatementRelationId");
 304  1
                 checkForNullOrEmptyParameter(nlUsageTypeKey, "nlUsageTypeKey");
 305  1
                 checkForEmptyParameter(language, "language");
 306  
 
 307  1
                 RefStatementRelation refStatementRelation = this.statementDao.fetch(RefStatementRelation.class, refStatementRelationId);
 308  1
                 Statement statement = refStatementRelation.getStatement();
 309  1
                 String nl = this.naturalLanguageTranslator.translateStatement(statement, nlUsageTypeKey, language);
 310  
 
 311  1
                 if(logger.isInfoEnabled()) {
 312  0
                         logger.info("refStatementRelationId="+refStatementRelationId);
 313  0
                         logger.info("nlUsageTypeKey="+nlUsageTypeKey);
 314  0
                         logger.info("language="+language);
 315  0
                         logger.info("Statement translation="+nl);
 316  
                 }
 317  
 
 318  1
                 return nl;
 319  
         }
 320  
 
 321  
         @Override
 322  
     @Transactional(readOnly=true)
 323  
         public String translateReqComponentToNL(final ReqComponentInfo reqComponentInfo, final String nlUsageTypeKey, final String language)
 324  
                         throws InvalidParameterException, MissingParameterException, OperationFailedException {
 325  1
                 checkForMissingParameter(reqComponentInfo, "reqComponentInfo");
 326  1
                 checkForNullOrEmptyParameter(nlUsageTypeKey, "nlUsageTypeKey");
 327  1
                 checkForEmptyParameter(language, "language");
 328  
 
 329  
                 try {
 330  
                         // test usage type key exists
 331  1
                         getNlUsageType(nlUsageTypeKey);
 332  1
                         ReqComponent req = statementAssembler.toReqComponentRelation(false, reqComponentInfo);
 333  1
                         String nl = this.naturalLanguageTranslator.translateReqComponent(req, nlUsageTypeKey, language);
 334  
 
 335  1
                         if(logger.isInfoEnabled()) {
 336  0
                             logger.info("ReqComponent translation="+nl);
 337  
                     }
 338  
 
 339  1
                         return nl;
 340  0
                 } catch (DoesNotExistException e) {
 341  0
                         throw new OperationFailedException("Requirement component translation failed: " + e.getMessage());
 342  0
                 } catch (VersionMismatchException e) {
 343  0
                         throw new OperationFailedException("Requirement component translation failed: " + e.getMessage());
 344  
                 }
 345  
         }
 346  
 
 347  
         @Override
 348  
     @Transactional(readOnly=true)
 349  
         public String translateStatementTreeViewToNL(final StatementTreeViewInfo statementTreeViewInfo, final String nlUsageTypeKey, final String language)
 350  
                         throws InvalidParameterException, MissingParameterException, OperationFailedException {
 351  0
                 checkForMissingParameter(statementTreeViewInfo, "statementTreeViewInfo");
 352  0
                 checkForNullOrEmptyParameter(nlUsageTypeKey, "nlUsageTypeKey");
 353  0
                 checkForEmptyParameter(language, "language");
 354  
 
 355  
                 try {
 356  0
                         Statement statement = statementAssembler.toStatement(statementTreeViewInfo);
 357  
 
 358  0
                         String nl = this.naturalLanguageTranslator.translateStatement(statement, nlUsageTypeKey, language);
 359  
 
 360  0
                         if(logger.isInfoEnabled()) {
 361  0
                             logger.info("StatementTreeView translation="+nl);
 362  
                     }
 363  
 
 364  0
                         return nl;
 365  0
                 } catch (DoesNotExistException e) {
 366  0
                         throw new OperationFailedException("Statement tree view translation failed: " + e.getMessage());
 367  0
                 } catch (VersionMismatchException e) {
 368  0
                         throw new OperationFailedException("Statement tree view translation failed: " + e.getMessage());
 369  
                 }
 370  
         }
 371  
 
 372  
         /**
 373  
          * Check for missing parameter and throw localized exception if missing
 374  
          *
 375  
          * @param param
 376  
          * @param parameter name
 377  
          * @throws MissingParameterException
 378  
          */
 379  
         private void checkForMissingParameter(Object param, String paramName)
 380  
                         throws MissingParameterException {
 381  83
                 if (param == null) {
 382  0
                         throw new MissingParameterException(paramName + " can not be null");
 383  
                 }
 384  83
         }
 385  
 
 386  
         /**
 387  
          * Check for missing or empty parameter and
 388  
          * throw localized exception if missing or empty
 389  
          *
 390  
          * @param param
 391  
          * @param parameter name
 392  
          * @throws MissingParameterException
 393  
          */
 394  
         private void checkForNullOrEmptyParameter(String param, String paramName)
 395  
                         throws MissingParameterException, InvalidParameterException {
 396  58
                 if (param == null) {
 397  2
                         throw new MissingParameterException(paramName + " can not be null");
 398  56
                 } else if (param.trim().isEmpty()) {
 399  2
                         throw new InvalidParameterException(paramName + " can not be empty");
 400  
                 }
 401  54
         }
 402  
 
 403  
         /**
 404  
          * Check for empty parameter and throw localized exception if empty
 405  
          *
 406  
          * @param param
 407  
          * @param parameter name
 408  
          * @throws MissingParameterException
 409  
          */
 410  
         private void checkForEmptyParameter(String param, String paramName)
 411  
                         throws MissingParameterException, InvalidParameterException {
 412  24
                 if (param != null && param.trim().isEmpty()) {
 413  0
                         throw new InvalidParameterException(paramName + " can not be empty");
 414  
                 }
 415  24
         }
 416  
 
 417  
     @Override
 418  
     @Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
 419  
         public ReqComponentInfo createReqComponent(final String reqComponentType, final ReqComponentInfo reqComponentInfo) throws AlreadyExistsException, DataValidationErrorException, DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
 420  5
         checkForMissingParameter(reqComponentType, "reqComponentType");
 421  5
         checkForMissingParameter(reqComponentInfo, "reqComponentInfo");
 422  
 
 423  5
         ReqComponent reqComp = null;
 424  
 
 425  
         try {
 426  5
             reqComp = statementAssembler.toReqComponentRelation(false, reqComponentInfo);
 427  0
         } catch (VersionMismatchException e) {
 428  0
             throw new OperationFailedException("Version Mismatch.", e);
 429  5
         }
 430  
 
 431  5
         reqComp = statementDao.create(reqComp);
 432  
 
 433  5
         return statementAssembler.toReqComponentInfo(reqComp, null, null);
 434  
     }
 435  
 
 436  
     @Override
 437  
     @Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
 438  
         public StatementInfo createStatement(final String statementType, final StatementInfo statementInfo) throws AlreadyExistsException, DataValidationErrorException, DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
 439  4
         checkForMissingParameter(statementType, "statementType");
 440  4
         checkForMissingParameter(statementInfo, "statementInfo");
 441  
 
 442  4
         Statement statement = null;
 443  
 
 444  
         try {
 445  4
             statement = statementAssembler.toStatementRelation(false, statementInfo);
 446  0
         } catch (VersionMismatchException e) {
 447  0
             throw new OperationFailedException("Version Mismatch.", e);
 448  4
         }
 449  
 
 450  4
         statementDao.create(statement);
 451  
 
 452  4
         StatementInfo info = StatementAssembler.toStatementInfo(statement);
 453  
 
 454  4
         return info;
 455  
     }
 456  
 
 457  
     @Override
 458  
     @Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
 459  
         public StatementTreeViewInfo createStatementTreeView(final StatementTreeViewInfo statementTreeViewInfo) throws AlreadyExistsException, DataValidationErrorException, DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, CircularReferenceException {
 460  
             try {
 461  
             // insert statements and reqComponents if they do not already exists in database
 462  1
             updateSTVHelperCreateStatements(statementTreeViewInfo);
 463  
 
 464  1
             updateStatementTreeViewHelper(statementTreeViewInfo);
 465  1
             StatementTreeViewInfo test = getStatementTreeView(statementTreeViewInfo.getId());
 466  
 
 467  1
             return test;
 468  0
                 } catch (VersionMismatchException e) {
 469  0
                         throw new OperationFailedException("Create failed.", e);
 470  
                 }
 471  
     }
 472  
 
 473  
     
 474  
     @Override
 475  
     @Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
 476  
         public StatusInfo deleteReqComponent(final String reqComponentId) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
 477  1
         checkForMissingParameter(reqComponentId, "reqComponentId");
 478  
 
 479  1
         ReqComponent reqComp = statementDao.fetch(ReqComponent.class, reqComponentId);
 480  
 
 481  1
         if(reqComp==null){
 482  0
             throw new DoesNotExistException("ReqComponent does not exist for id: "+reqComponentId);
 483  
         }
 484  
 
 485  1
         statementDao.delete(reqComp);
 486  
 
 487  1
         StatusInfo statusInfo = new StatusInfo();
 488  1
         statusInfo.setSuccess(true);
 489  1
         statusInfo.setMessage("Requirement component successfully deleted");
 490  1
         return statusInfo;
 491  
     }
 492  
 
 493  
     @Override
 494  
     @Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
 495  
         public StatusInfo deleteStatement(final String statementId) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
 496  1
         checkForMissingParameter(statementId, "statementId");
 497  
 
 498  1
         Statement stmt = statementDao.fetch(Statement.class, statementId);
 499  1
         if(stmt==null){
 500  0
             throw new DoesNotExistException("Statement does not exist for id: "+statementId);
 501  
         }
 502  
 
 503  
 
 504  
                 try {
 505  1
                         Statement parent = statementDao.getParentStatement(statementId);
 506  1
                 List<Statement> children = parent.getChildren();
 507  1
                 for (int i = 0; i < children.size(); i++) {
 508  1
                         if (children.get(i).getId().equals(statementId)) {
 509  1
                                 children.remove(i);
 510  1
                                 break;
 511  
                         }
 512  
                 }
 513  1
                 statementDao.update(parent);
 514  0
                 } catch (DoesNotExistException e) {
 515  
                         // Ignore in this case
 516  1
                 }
 517  
 
 518  1
         statementDao.delete(stmt);
 519  
 
 520  1
         StatusInfo statusInfo = new StatusInfo();
 521  1
         statusInfo.setSuccess(true);
 522  1
         statusInfo.setMessage("Statement successfully deleted");
 523  1
         return statusInfo;
 524  
     }
 525  
     
 526  
     @Override
 527  
     @Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
 528  
         public StatusInfo deleteStatementTreeView(final String statementId) throws DoesNotExistException{
 529  1
         Statement stmt = statementDao.fetch(Statement.class, statementId);
 530  
         
 531  
         try{
 532  1
                 Statement parent = statementDao.getParentStatement(statementId);
 533  
                 
 534  
                 //remove the child from the parent
 535  0
             if(parent.getChildren()!=null){
 536  0
                         for(Iterator<Statement> iter = parent.getChildren().iterator();iter.hasNext();){
 537  0
                                 Statement childStmt = iter.next();
 538  0
                                 if(stmt.getId().equals(childStmt.getId())){
 539  0
                                         iter.remove();
 540  0
                                         break;
 541  
                                 }
 542  0
                         }
 543  
                 }
 544  0
                 statementDao.update(parent);
 545  1
             }catch(DoesNotExistException e){
 546  
                     //Ignore in this case
 547  0
             }
 548  
         
 549  
         //delete the tree hierarchy;
 550  1
         deleteRecursively(stmt);
 551  
         
 552  1
         StatusInfo statusInfo = new StatusInfo();
 553  1
         statusInfo.setSuccess(true);
 554  1
         statusInfo.setMessage("Statement Tree successfully deleted");
 555  1
         return statusInfo;
 556  
     }
 557  
 
 558  
         private void deleteRecursively(Statement stmt) {
 559  3
             if(stmt.getChildren()!=null){
 560  3
                     List<Statement> childStmts = new ArrayList<Statement>(stmt.getChildren());
 561  3
                     stmt.getChildren().clear();
 562  3
                     stmt = statementDao.update(stmt);
 563  3
                     for(Statement childStmt:childStmts){
 564  2
                             deleteRecursively(childStmt);
 565  
                     }
 566  
             }
 567  3
             statementDao.delete(stmt);
 568  3
         }
 569  
 
 570  
         @Override
 571  
     @Transactional(readOnly=true)
 572  
     public ReqComponentInfo getReqComponent(final String reqComponentId) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 573  10
         return statementAssembler.toReqComponentInfo(statementDao.fetch(ReqComponent.class, reqComponentId), null, null);
 574  
     }
 575  
 
 576  
     @Override
 577  
     @Transactional(readOnly=true)
 578  
     public List<ReqComponentInfo> getReqComponentsByType(final String reqComponentTypeKey) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 579  2
         checkForMissingParameter(reqComponentTypeKey, "reqComponentTypeKey");
 580  
 
 581  2
         List<ReqComponent> reqComponents = statementDao.getReqComponentsByType(reqComponentTypeKey);
 582  2
         return statementAssembler.toReqComponentInfos(reqComponents, null, null);
 583  
     }
 584  
 
 585  
     @Override
 586  
     @Transactional(readOnly=true)
 587  
     public StatementInfo getStatement(final String statementId) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 588  17
         StatementInfo statementInfo = null;
 589  17
         checkForMissingParameter(statementId, "statementId");
 590  17
         statementInfo = StatementAssembler.toStatementInfo(statementDao.fetch(Statement.class, statementId));
 591  12
         return statementInfo;
 592  
     }
 593  
 
 594  
     @Override
 595  
     @Transactional(readOnly=true)
 596  
     public List<StatementInfo> getStatementsByType(final String statementTypeKey) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 597  2
         checkForMissingParameter(statementTypeKey, "statementTypeKey");
 598  
 
 599  2
         List<Statement> statements = statementDao.getStatementsForStatementType(statementTypeKey);
 600  2
         return StatementAssembler.toStatementInfos(statements);
 601  
     }
 602  
 
 603  
     @Override
 604  
     @Transactional(readOnly=true)
 605  
     public List<StatementInfo> getStatementsUsingReqComponent(final String reqComponentId) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 606  1
         checkForNullOrEmptyParameter(reqComponentId, "reqComponentId");
 607  
 
 608  1
         List<Statement> list = statementDao.getStatementsForReqComponent(reqComponentId);
 609  1
         return StatementAssembler.toStatementInfos(list);
 610  
     }
 611  
 
 612  
     /**
 613  
      * Gets child statements but does no downward recursion of child statements.
 614  
      *
 615  
      * @param statementId statement identifier
 616  
      * @return List of child statements using the specified statement
 617  
      * @throws DoesNotExistException Statement not found
 618  
      * @throws InvalidParameterException Invalid statementId
 619  
      * @throws MissingParameterException statementId not specified
 620  
      * @throws OperationFailedException Unable to complete request
 621  
      */
 622  
     @Transactional(readOnly=true)
 623  
         public List<StatementInfo> getStatementsUsingStatement(final String statementId)
 624  
                         throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 625  1
         checkForNullOrEmptyParameter(statementId, "statementId");
 626  
 
 627  1
                 Statement statement = statementDao.fetch(Statement.class, statementId);
 628  1
                 List<StatementInfo> list = StatementAssembler.toStatementInfos(statement.getChildren());
 629  1
                 return list;
 630  
         }
 631  
 
 632  
     @Override
 633  
     @Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
 634  
         public StatementInfo updateStatement(final String statementId, final StatementInfo statementInfo) throws CircularReferenceException, DataValidationErrorException, DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, VersionMismatchException {
 635  
         //Check Missing params
 636  5
         checkForMissingParameter(statementId, "statementId");
 637  5
         checkForMissingParameter(statementInfo, "statementInfo");
 638  
 
 639  
         //Set all the values on statementInfo
 640  5
         statementInfo.setId(statementId);
 641  
 
 642  
         //Update persistence entity from the statementInfo
 643  5
         Statement stmt = statementAssembler.toStatementRelation(true, statementInfo);
 644  
 
 645  
         //Update the statement
 646  4
         Statement updatedStmt = statementDao.update(stmt);
 647  
 
 648  
         //Copy back to an statementInfo and return
 649  4
         StatementInfo updStatementInfo = StatementAssembler.toStatementInfo(updatedStmt);
 650  4
         return updStatementInfo;
 651  
     }
 652  
 
 653  
     @Override
 654  
     public List<ValidationResultInfo> validateReqComponent(final String validationType, final ReqComponentInfo reqComponentInfo) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 655  3
         checkForMissingParameter(validationType, "validationType");
 656  3
         checkForMissingParameter(reqComponentInfo, "reqComponentInfo");
 657  
 
 658  3
         ObjectStructureDefinition objStructure = this.getObjectStructure(ReqComponentInfo.class.getName());
 659  3
         Validator defaultValidator = validatorFactory.getValidator();
 660  3
         List<ValidationResultInfo> validationResults = defaultValidator.validateObject(reqComponentInfo, objStructure);
 661  
 
 662  3
         return validationResults;
 663  
     }
 664  
 
 665  
     @Override
 666  
     public List<ValidationResultInfo> validateStatement(final String validationType, final StatementInfo statementInfo) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 667  0
         checkForMissingParameter(validationType, "validationType");
 668  0
         checkForMissingParameter(statementInfo, "statementInfo");
 669  
 
 670  0
         ObjectStructureDefinition objStructure = this.getObjectStructure(StatementInfo.class.getName());
 671  0
         Validator defaultValidator = validatorFactory.getValidator();
 672  0
         List<ValidationResultInfo> validationResults = defaultValidator.validateObject(statementInfo, objStructure);
 673  
 
 674  0
         return validationResults;
 675  
     }
 676  
 
 677  
     @Override
 678  
     public ObjectStructureDefinition getObjectStructure(String objectTypeKey) {
 679  8
         return dictionaryServiceDelegate.getObjectStructure(objectTypeKey);
 680  
     }
 681  
 
 682  
     @Override
 683  
     public SearchCriteriaTypeInfo getSearchCriteriaType(final String searchCriteriaTypeKey) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 684  0
         return searchManager.getSearchCriteriaType(searchCriteriaTypeKey);
 685  
     }
 686  
 
 687  
     @Override
 688  
     public List<SearchCriteriaTypeInfo> getSearchCriteriaTypes() throws OperationFailedException {
 689  0
         return searchManager.getSearchCriteriaTypes();
 690  
     }
 691  
 
 692  
     @Override
 693  
     public SearchResultTypeInfo getSearchResultType(final String searchResultTypeKey) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 694  0
         checkForMissingParameter(searchResultTypeKey, "searchResultTypeKey");
 695  0
         return searchManager.getSearchResultType(searchResultTypeKey);
 696  
     }
 697  
 
 698  
     @Override
 699  
     public List<SearchResultTypeInfo> getSearchResultTypes() throws OperationFailedException {
 700  0
         return searchManager.getSearchResultTypes();
 701  
     }
 702  
 
 703  
     @Override
 704  
     public SearchTypeInfo getSearchType(final String searchTypeKey) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 705  0
         checkForMissingParameter(searchTypeKey, "searchTypeKey");
 706  0
         return searchManager.getSearchType(searchTypeKey);
 707  
     }
 708  
 
 709  
     @Override
 710  
     public List<SearchTypeInfo> getSearchTypes() throws OperationFailedException {
 711  0
         return searchManager.getSearchTypes();
 712  
     }
 713  
 
 714  
     @Override
 715  
     public List<SearchTypeInfo> getSearchTypesByCriteria(final String searchCriteriaTypeKey) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 716  0
         checkForMissingParameter(searchCriteriaTypeKey, "searchCriteriaTypeKey");
 717  0
         return searchManager.getSearchTypesByCriteria(searchCriteriaTypeKey);
 718  
     }
 719  
 
 720  
     @Override
 721  
     public List<SearchTypeInfo> getSearchTypesByResult(final String searchResultTypeKey) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 722  0
         checkForMissingParameter(searchResultTypeKey, "searchResultTypeKey");
 723  0
         return searchManager.getSearchTypesByResult(searchResultTypeKey);
 724  
     }
 725  
 
 726  
         @Override
 727  
     public SearchResult search(final SearchRequest searchRequest) throws MissingParameterException {
 728  1
         checkForMissingParameter(searchRequest, "searchRequest");
 729  1
         if(SEARCH_KEY_DEPENDENCY_ANALYSIS.equals(searchRequest.getSearchKey())){
 730  
                 //Special case for dependency analysis.
 731  
                 //Parse out query params and execute custom search
 732  0
                 List<String> cluVersionIndIds = new ArrayList<String>();
 733  0
                 List<String> cluSetIds = new ArrayList<String>();
 734  0
                     for(SearchParam param:searchRequest.getParams()){
 735  0
                             if("stmt.queryParam.cluSetIds".equals(param.getKey())){
 736  0
                                     cluSetIds.addAll((List<String>)param.getValue());
 737  0
                                     continue;
 738  0
                             }else if("stmt.queryParam.cluVersionIndIds".equals(param.getKey())){
 739  0
                                     cluVersionIndIds.addAll((List<String>)param.getValue());
 740  
                             }
 741  
                     }
 742  0
                     if(cluVersionIndIds.isEmpty()){
 743  0
                             cluVersionIndIds.add("");
 744  
                     }
 745  0
                     if(cluSetIds.isEmpty()){
 746  0
                             cluSetIds.add("");
 747  
                     }
 748  0
                         return doDependencyAnalysisSearch(cluVersionIndIds,cluSetIds);
 749  
         }
 750  
         
 751  1
         return searchManager.search(searchRequest, statementDao);
 752  
     }
 753  
 
 754  
     private SearchResult doDependencyAnalysisSearch(
 755  
                         List<String> cluVersionIndIds, List<String> cluSetIds) {
 756  
             //First look up all the statements that have requirement components that reference the 
 757  
             //given cluIds and clusets
 758  0
             List<Object[]> results = statementDao.getStatementsWithDependencies(cluVersionIndIds,cluSetIds);
 759  
             
 760  
             //From the Object[], which contains a statement at index 0, and a result component id at index 1
 761  
             //obtain a list of statements and a comma delimited list of requirement component ids for each 
 762  
             //statement which contain the target clu/cluset
 763  0
             Map<String,String> statementToResultComponentIds = new HashMap<String,String>();
 764  0
             Map<String, Statement> statements = new HashMap<String,Statement>();
 765  0
             for(Object[] result:results){
 766  0
                     Statement statement = (Statement) result[0];
 767  0
                     statements.put(statement.getId(),statement);
 768  0
                     String resultComponentIds = statementToResultComponentIds.get(statement.getId());
 769  0
                     if(resultComponentIds == null){
 770  0
                             resultComponentIds = (String)result[1];
 771  
                     }else{
 772  0
                             resultComponentIds+="," + (String)result[1];
 773  
                     }
 774  0
                     statementToResultComponentIds.put(statement.getId(), resultComponentIds);
 775  0
             }
 776  
             
 777  
             
 778  
             //HashMap of root statements used to store non duplicate root statements 
 779  0
             Map<String,Statement> rootStatements = new HashMap<String,Statement>();
 780  
             
 781  0
             Map<String,String> rootToRequirementComponentList = new HashMap<String,String>();
 782  
             
 783  
             //Next find the root statements since only the root is related to a clu
 784  0
             for(Statement statement:statements.values()){
 785  0
                     Statement child = statement;
 786  0
                     Statement parent = child;
 787  0
                     while(parent!=null){
 788  
                             try{
 789  
                                     //Search for parent of this child
 790  0
                                     parent = statementDao.getParentStatement(child.getId());
 791  0
                                     child = parent;
 792  0
                             }catch(DoesNotExistException e){
 793  
                                     //This is the root (no parent) so add to list of roots
 794  0
                                     rootStatements.put(child.getId(), child);
 795  
                                     
 796  
                                     //Create a comma delimited mapping of all the requirement components
 797  
                                     //ids that contain the trigger clu within this root statement
 798  0
                                 String childStatementList = rootToRequirementComponentList.get(child.getId());
 799  0
                                 if(childStatementList==null){
 800  0
                                         childStatementList = statementToResultComponentIds.get(statement.getId());
 801  
                                 }else{
 802  0
                                         childStatementList += ","+statementToResultComponentIds.get(statement.getId());
 803  
                                 }
 804  0
                                 rootToRequirementComponentList.put(child.getId(), childStatementList);
 805  
                                     
 806  
                                     //Exit condition(hopefully there are no cyclic statements)
 807  0
                                     parent = null;
 808  0
                             }
 809  
                     }
 810  0
             }
 811  
             
 812  0
             SearchResult searchResult = new SearchResult();
 813  
             
 814  
             //Record each statement's reference id type and reference type as a search result row
 815  
             //Use a hashset of the cell values to remove duplicates
 816  0
             Set<String> processed = new HashSet<String>();
 817  0
             for(Statement statement:rootStatements.values()){
 818  0
                     for(RefStatementRelation relation:statement.getRefStatementRelations()){
 819  0
                             String rowId = relation.getRefObjectId()+"|"+relation.getRefObjectTypeKey();
 820  0
                             if(!processed.contains(rowId)){
 821  
                                     //This row does not exist yet so we can add it to the results.
 822  0
                                     processed.add(rowId);
 823  0
                                     SearchResultRow row = new SearchResultRow();
 824  0
                                     row.addCell("stmt.resultColumn.refObjId",relation.getRefObjectId());
 825  0
                                     row.addCell("stmt.resultColumn.rootId",statement.getId());
 826  0
                                     row.addCell("stmt.resultColumn.requirementComponentIds",rootToRequirementComponentList.get(statement.getId()));
 827  0
                                     row.addCell("stmt.resultColumn.statementTypeId",statement.getStatementType().getId());
 828  0
                                     row.addCell("stmt.resultColumn.statementTypeName",statement.getStatementType().getName());
 829  0
                                      searchResult.getRows().add(row);
 830  
                             }
 831  0
                     }
 832  
             }
 833  
             
 834  0
                 return searchResult;
 835  
         }
 836  
 
 837  
         @Override
 838  
     public List<String> getObjectTypes() {
 839  0
         return dictionaryServiceDelegate.getObjectTypes();
 840  
     }
 841  
 
 842  
     @Override
 843  
     @Transactional(readOnly=true)
 844  
     public StatementTypeInfo getStatementType(final String statementTypeKey) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 845  1
         return StatementAssembler.toStatementTypeInfo(statementDao.fetch(StatementType.class, statementTypeKey));
 846  
     }
 847  
 
 848  
     @Override
 849  
     @Transactional(readOnly=true)
 850  
     public List<StatementTypeInfo> getStatementTypes() throws OperationFailedException {
 851  1
         return StatementAssembler.toStatementTypeInfos(statementDao.find(StatementType.class));
 852  
     }
 853  
 
 854  
     @Transactional(readOnly=true)
 855  
     public List<String> getStatementTypesForStatementType(final String statementTypeKey) throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 856  1
             StatementTypeInfo type = StatementAssembler.toStatementTypeInfo(statementDao.fetch(StatementType.class, statementTypeKey));
 857  1
             return type.getAllowedStatementTypes();
 858  
     }
 859  
 
 860  
     @Override
 861  
     @Transactional(readOnly=true)
 862  
     public List<ReqComponentTypeInfo> getReqComponentTypes() throws OperationFailedException {
 863  1
         return StatementAssembler.toReqComponentTypeInfos(statementDao.find(ReqComponentType.class));
 864  
     }
 865  
 
 866  
     @Override
 867  
     @Transactional(readOnly=true)
 868  
     public ReqComponentTypeInfo getReqComponentType(final String reqComponentTypeKey)
 869  
                     throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 870  3
         return StatementAssembler.toReqComponentTypeInfo(statementDao.fetch(ReqComponentType.class, reqComponentTypeKey));
 871  
     }
 872  
 
 873  
     @Override
 874  
     @Transactional(readOnly=true)
 875  
     public List<ReqComponentTypeInfo> getReqComponentTypesForStatementType(final String statementTypeKey)
 876  
                         throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 877  1
         checkForMissingParameter(statementTypeKey, "statementTypeKey");
 878  
 
 879  1
         StatementType stmtType = statementDao.fetch(StatementType.class, statementTypeKey);
 880  1
         if(null == stmtType) {
 881  0
             throw new DoesNotExistException("Statement Type: " + statementTypeKey + " does not exist.");
 882  
         }
 883  
 
 884  1
         return StatementAssembler.toReqComponentTypeInfosOrdered( stmtType.getAllowedReqComponentTypes() );
 885  
     }
 886  
 
 887  
     @Override
 888  
     @Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
 889  
         public ReqComponentInfo updateReqComponent(final String reqComponentId, final ReqComponentInfo reqComponentInfo)
 890  
                     throws DataValidationErrorException, DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, VersionMismatchException {
 891  
         //Check Missing params
 892  7
         checkForMissingParameter(reqComponentId, "reqComponentId");
 893  7
         checkForMissingParameter(reqComponentInfo, "reqComponentInfo");
 894  
 
 895  
         //Set all the values on reqComponentInfo
 896  7
         reqComponentInfo.setId(reqComponentId);
 897  
 
 898  7
         ReqComponent reqComp = null;
 899  
 
 900  
         //Update persistence entity from the reqComponentInfo
 901  7
         reqComp = statementAssembler.toReqComponentRelation(true, reqComponentInfo);
 902  
 
 903  
         //Update the reqComponen
 904  6
         ReqComponent updatedReqComp = statementDao.update(reqComp);
 905  
 
 906  
         //Copy back to an reqComponentInfo and return
 907  6
         ReqComponentInfo updReqCompInfo = StatementAssembler.toReqComponentInfo(updatedReqComp);
 908  6
         return updReqCompInfo;
 909  
     }
 910  
 
 911  
         @Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
 912  
         public RefStatementRelationInfo createRefStatementRelation(final RefStatementRelationInfo refStatementRelationInfo)
 913  
                         throws AlreadyExistsException, DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
 914  6
                 checkForMissingParameter(refStatementRelationInfo, "refStatementRelationInfo");
 915  
 
 916  6
                 Statement statement = this.statementDao.fetch(Statement.class, refStatementRelationInfo.getStatementId());
 917  6
                 RefStatementRelationType type = this.statementDao.fetch(RefStatementRelationType.class, refStatementRelationInfo.getType());
 918  
 
 919  
         // make sure refObjectType exist
 920  6
         this.statementDao.fetch(ObjectType.class, refStatementRelationInfo.getRefObjectTypeKey());
 921  
                 
 922  6
                 RefStatementRelation entity = new RefStatementRelation();
 923  
 
 924  6
                 BeanUtils.copyProperties(refStatementRelationInfo, entity, new String[] {
 925  
                                 "statementId", "attributes", "metaInfo", "type", "id"});
 926  
 
 927  6
                 entity.setRefStatementRelationType(type);
 928  6
                 entity.setStatement(statement);
 929  
 
 930  6
                 List<RefStatementRelationAttribute> attributes = StatementAssembler.toGenericAttributes(RefStatementRelationAttribute.class, refStatementRelationInfo.getAttributes(), entity, this.statementDao);
 931  6
                 entity.setAttributes(attributes);
 932  
 
 933  6
                 RefStatementRelation newEntity = this.statementDao.create(entity);
 934  
 
 935  6
                 RefStatementRelationInfo newDto = StatementAssembler.toRefStatementRelationInfo(newEntity);
 936  
 
 937  6
                 return newDto;
 938  
         }
 939  
 
 940  
         @Override
 941  
         @Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
 942  
         public RefStatementRelationInfo updateRefStatementRelation(final String refStatementRelationId, final RefStatementRelationInfo refStatementRelationInfo)
 943  
                         throws DataValidationErrorException, DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, VersionMismatchException {
 944  3
                 checkForNullOrEmptyParameter(refStatementRelationId, "refStatementRelationId");
 945  3
                 checkForMissingParameter(refStatementRelationInfo, "refStatementRelationInfo");
 946  
 
 947  3
                 refStatementRelationInfo.setId(refStatementRelationId);
 948  3
                 RefStatementRelation refStatementRel = statementAssembler.toRefStatementRelation(true, refStatementRelationInfo);
 949  1
                 RefStatementRelation updatedRefStatementRel = statementDao.update(refStatementRel);
 950  
 
 951  1
                 RefStatementRelationInfo dto = StatementAssembler.toRefStatementRelationInfo(updatedRefStatementRel);
 952  1
                 return dto;
 953  
         }
 954  
 
 955  
         @Override
 956  
         @Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
 957  
         public StatusInfo deleteRefStatementRelation(final String refStatementRelationId)
 958  
                         throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException {
 959  10
                 checkForNullOrEmptyParameter(refStatementRelationId, "refStatementRelationId");
 960  8
                 this.statementDao.delete(RefStatementRelation.class, refStatementRelationId);
 961  
 
 962  6
         StatusInfo statusInfo = new StatusInfo();
 963  6
         statusInfo.setSuccess(true);
 964  6
         statusInfo.setMessage("Reference statement relation successfully deleted");
 965  6
         return statusInfo;
 966  
         }
 967  
 
 968  
         @Override
 969  
         public List<ValidationResultInfo> validateRefStatementRelation(final String validationType, RefStatementRelationInfo refStatementRelationInfo)
 970  
                         throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 971  1
         ObjectStructureDefinition objStructure = this.getObjectStructure(RefStatementRelationInfo.class.getName());
 972  1
         Validator defaultValidator = validatorFactory.getValidator();
 973  1
         List<ValidationResultInfo> validationResults = defaultValidator.validateObject(refStatementRelationInfo, objStructure);
 974  
 
 975  1
                 return validationResults;
 976  
         }
 977  
 
 978  
     @Override
 979  
     @Transactional(readOnly=true)
 980  
     public StatementTreeViewInfo getStatementTreeView(final String statementId)
 981  
             throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 982  5
             checkForNullOrEmptyParameter("statementId", statementId);
 983  
 
 984  5
             return getStatementTreeView(statementId, null, null);
 985  
     }
 986  
 
 987  
     @Override
 988  
     @Transactional(readOnly=true)
 989  
     public StatementTreeViewInfo getStatementTreeViewForNlUsageType(final String statementId, final String nlUsageTypeKey, final String language)
 990  
                 throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 991  0
             checkForNullOrEmptyParameter("statementId", statementId);
 992  0
             checkForNullOrEmptyParameter("nlUsageTypeKey", nlUsageTypeKey);
 993  0
             checkForNullOrEmptyParameter("language", language);
 994  
 
 995  0
             return getStatementTreeView(statementId, nlUsageTypeKey, language);
 996  
     }
 997  
 
 998  
     private StatementTreeViewInfo getStatementTreeView(final String statementId, final String nlUsageTypeKey, final String language)
 999  
             throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 1000  5
         StatementTreeViewInfo statementTreeViewInfo = null;
 1001  5
         StatementInfo statementInfo = getStatement(statementId);
 1002  2
         if (statementInfo == null) return null;
 1003  2
         statementTreeViewInfo = new StatementTreeViewInfo();
 1004  2
         getStatementTreeViewHelper(statementInfo, statementTreeViewInfo, nlUsageTypeKey, language);
 1005  2
         return statementTreeViewInfo;
 1006  
 
 1007  
 
 1008  
             /*
 1009  
             Map<String, String> configuration = new HashMap<String, String>();
 1010  
             configuration.put("USAGE_TYPE_KEY", nlUsageTypeKey);
 1011  
             configuration.put("NL_KEY", language);
 1012  
             StatementTreeViewInfo result = new StatementTreeViewInfo();
 1013  
             try {
 1014  
                         statementTreeViewAssembler.assemble(getStatement(statementId), result, false, configuration);
 1015  
                         return result;
 1016  
             } catch (AssemblyException e) {
 1017  
                         throw new OperationFailedException(e.getMessage(), e);
 1018  
                 }
 1019  
                 */
 1020  
     }
 1021  
 
 1022  
 
 1023  
     /**
 1024  
      * Goes through the list of reqComponentIds in statementInfo and retrieves the reqComponentInfos being referenced
 1025  
      * @param statementInfo
 1026  
      * @return list of reqComponentInfo referenced by the list of reqComponentIds in statementInfo
 1027  
      * @throws DoesNotExistException
 1028  
      * @throws InvalidParameterException
 1029  
      * @throws MissingParameterException
 1030  
      * @throws OperationFailedException
 1031  
      */
 1032  
     private List<ReqComponentInfo> getReqComponentInfos(final StatementInfo statementInfo, final String nlUsageTypeKey, final String language)
 1033  
             throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 1034  6
         List<ReqComponentInfo> reqComponentInfos = new ArrayList<ReqComponentInfo>();
 1035  6
         if (statementInfo == null) return null;
 1036  6
         if (statementInfo.getReqComponentIds() != null) {
 1037  6
             for (String reqComponentId : statementInfo.getReqComponentIds()) {
 1038  
                 //ReqComponentInfo reqCompInfo = getReqComponent(reqComponentId);
 1039  8
                     ReqComponentInfo reqCompInfo = statementAssembler.toReqComponentInfo(statementDao.fetch(ReqComponent.class, reqComponentId), nlUsageTypeKey, language);
 1040  8
                 reqComponentInfos.add(reqCompInfo);
 1041  8
             }
 1042  
         }
 1043  6
         return reqComponentInfos;
 1044  
     }
 1045  
 
 1046  
     /**
 1047  
      * Goes through the list of statementIds in statementInfo and retrieves all
 1048  
      * information regarding to the current statementInfo and all the
 1049  
      * sub-statements referenced by statementIds.  Data will be populated into
 1050  
      * statementTreeViewInfo
 1051  
      * @param statementInfo
 1052  
      * @return void
 1053  
      * @throws DoesNotExistException
 1054  
      * @throws InvalidParameterException
 1055  
      * @throws MissingParameterException
 1056  
      * @throws OperationFailedException
 1057  
      */
 1058  
     private void getStatementTreeViewHelper(final StatementInfo statementInfo, final StatementTreeViewInfo statementTreeViewInfo,
 1059  
                     final String nlUsageTypeKey, final String language)
 1060  
             throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 1061  6
         if (statementInfo == null) return;
 1062  
 
 1063  6
         statementAssembler.copyValues(statementTreeViewInfo, statementInfo);
 1064  6
         statementTreeViewInfo.setReqComponents(getReqComponentInfos(statementInfo, nlUsageTypeKey, language));
 1065  
         // get statements recursively and convert them into statementTreeViewInfo
 1066  6
         if (statementInfo.getStatementIds() != null) {
 1067  6
             for (String statementId : statementInfo.getStatementIds()) {
 1068  4
                 StatementInfo subStatement = getStatement(statementId);
 1069  
 
 1070  4
                 List<StatementTreeViewInfo> statements =
 1071  
                     (statementTreeViewInfo.getStatements() == null) ? new ArrayList<StatementTreeViewInfo>() : statementTreeViewInfo.getStatements();
 1072  4
                 StatementTreeViewInfo subStatementTreeViewInfo = new StatementTreeViewInfo();
 1073  
 
 1074  
                 // recursive call to get subStatementTreeViewInfo
 1075  4
                 getStatementTreeViewHelper(subStatement, subStatementTreeViewInfo, nlUsageTypeKey, language);
 1076  4
                 statements.add(subStatementTreeViewInfo);
 1077  4
                 statementTreeViewInfo.setStatements(statements);
 1078  4
             }
 1079  
         }
 1080  6
     }
 1081  
 
 1082  
     @Override
 1083  
     @Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
 1084  
         public StatementTreeViewInfo updateStatementTreeView(final String statementId, final StatementTreeViewInfo statementTreeViewInfo)
 1085  
             throws CircularReferenceException, DataValidationErrorException, DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, VersionMismatchException {
 1086  
                 
 1087  0
                 Statement stmt = this.statementDao.fetch(Statement.class, statementTreeViewInfo.getId());
 1088  0
             if (stmt == null) {
 1089  0
                 throw new DoesNotExistException("Statement does not exist for id: " + statementTreeViewInfo.getId());
 1090  
                 }
 1091  0
                 if (!String.valueOf(stmt.getVersionNumber()).equals(statementTreeViewInfo.getMetaInfo().getVersionInd())) {
 1092  0
                     throw new VersionMismatchException("Statement to be updated is not the current version");
 1093  
                 }
 1094  
                    
 1095  0
             Set<String> statementIdsToDelete = new HashSet<String>();
 1096  0
             List<ReqComponent> requirementComponentsToCreate = new ArrayList<ReqComponent>();
 1097  0
             List<Statement> statmentsToUpdate = new ArrayList<Statement>();
 1098  
             
 1099  
             //Transform the tree into a statement with all of its children
 1100  0
             stmt = statementAssembler.toStatementFromTree(stmt, statementTreeViewInfo, statementIdsToDelete, statmentsToUpdate, requirementComponentsToCreate);
 1101  
                 
 1102  
             //Create any new reqComponents 
 1103  0
             for(ReqComponent reqComponent:requirementComponentsToCreate){
 1104  0
                         statementDao.create(reqComponent);
 1105  
                 }
 1106  
             
 1107  
             //Update the actual statement
 1108  0
             stmt = statementDao.update(stmt);
 1109  
             
 1110  
             //Update statements where the join table needs to be cleared
 1111  
             
 1112  
             //delete orphaned statements
 1113  0
             for(String statementIdToDelete:statementIdsToDelete){
 1114  0
                     statementDao.delete(Statement.class, statementIdToDelete);
 1115  
             }
 1116  
             
 1117  
             //Transform back to a dto
 1118  0
             StatementTreeViewInfo result = statementAssembler.toStatementTreeViewInfo(stmt);
 1119  
         
 1120  0
                 return result;
 1121  
 
 1122  
 
 1123  
     }
 1124  
 
 1125  
     /*private List<String> notIn(
 1126  
             StatementTreeViewInfo oldTree,
 1127  
             StatementTreeViewInfo newTree) {
 1128  
         List<String> results = new ArrayList<String>(17);
 1129  
         List<String> oldStatementIds = new ArrayList<String>(17);
 1130  
         List<String> newStatementIds = new ArrayList<String>(17);
 1131  
         getStatementIds(oldTree, oldStatementIds);
 1132  
         getStatementIds(newTree, newStatementIds);
 1133  
         if (oldStatementIds != null) {
 1134  
             for (String oldStatementId : oldStatementIds) {
 1135  
                 boolean inNewStatementIds = false;
 1136  
                 if (newStatementIds != null) {
 1137  
                     for (String newStatementId : newStatementIds) {
 1138  
                         if (oldStatementId.equals(newStatementId)) {
 1139  
                             inNewStatementIds = true;
 1140  
                         }
 1141  
                     }
 1142  
                 }
 1143  
                 if (!inNewStatementIds) {
 1144  
                     results.add(oldStatementId);
 1145  
                 }
 1146  
             }
 1147  
         }
 1148  
         return results;
 1149  
     }
 1150  
 
 1151  
     private void getStatementIds(StatementTreeViewInfo statementTreeViewInfo, List<String> statementIds) {
 1152  
         if (statementTreeViewInfo.getStatements() != null) {
 1153  
             for (StatementTreeViewInfo subTree : statementTreeViewInfo.getStatements()) {
 1154  
                 getStatementIds(subTree, statementIds);
 1155  
             }
 1156  
         }
 1157  
         statementIds.add(statementTreeViewInfo.getId());
 1158  
     }*/
 1159  
 
 1160  
         private void updateStatementTreeViewHelper(StatementTreeViewInfo statementTreeViewInfo) throws CircularReferenceException, DataValidationErrorException, DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, VersionMismatchException {
 1161  3
         if (statementTreeViewInfo.getStatements() != null) {
 1162  3
             for (StatementTreeViewInfo subStatement : statementTreeViewInfo.getStatements()) {
 1163  2
                 updateStatementTreeViewHelper(subStatement);
 1164  
             }
 1165  
         }
 1166  3
         if (statementTreeViewInfo.getReqComponents() != null) {
 1167  3
             List<ReqComponentInfo> updatedReqComponentInfos = new ArrayList<ReqComponentInfo>(7);
 1168  3
             for (ReqComponentInfo reqComponentInfo : statementTreeViewInfo.getReqComponents()) {
 1169  4
                 ReqComponentInfo updatedReqComponentInfo = updateReqComponent(reqComponentInfo.getId(), reqComponentInfo);
 1170  4
                 updatedReqComponentInfos.add(updatedReqComponentInfo);
 1171  4
             }
 1172  3
             statementTreeViewInfo.setReqComponents(updatedReqComponentInfos);
 1173  
         }
 1174  3
         StatementInfo updatedStatementInfo = updateStatement(statementTreeViewInfo.getId(), statementAssembler.toStatementInfo(
 1175  
                 statementTreeViewInfo));
 1176  3
         statementAssembler.copyValues(statementTreeViewInfo, updatedStatementInfo);
 1177  3
     }
 1178  
 
 1179  
         private void updateSTVHelperCreateStatements(StatementTreeViewInfo statementTreeViewInfo) throws CircularReferenceException, DataValidationErrorException, DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException, PermissionDeniedException, VersionMismatchException {
 1180  3
         String statementId = null;
 1181  3
         StatementInfo origStatementInfo = null;
 1182  3
         StatementInfo newStatementInfo = null;
 1183  3
         if (statementTreeViewInfo.getStatements() != null) {
 1184  3
             for (StatementTreeViewInfo subTreeInfo : statementTreeViewInfo.getStatements()) {
 1185  2
                 updateSTVHelperCreateStatements(subTreeInfo);
 1186  
             }
 1187  
         }
 1188  3
         if (statementTreeViewInfo.getReqComponents() != null) {
 1189  3
             List<ReqComponentInfo> rcsAfterInserts = new ArrayList<ReqComponentInfo>(7);
 1190  3
             for (ReqComponentInfo reqComponentInfo : statementTreeViewInfo.getReqComponents()) {
 1191  4
                 String reqComponentId = reqComponentInfo.getId();
 1192  4
                 ReqComponentInfo origReqComponentInfo = null;
 1193  4
                 ReqComponentInfo rcAfterInsert = null;
 1194  
                 // determine the original reqComponentInfo
 1195  4
                 if (reqComponentId != null) {
 1196  
                     try {
 1197  0
                         origReqComponentInfo = getReqComponent(reqComponentId);
 1198  0
                     } catch (DoesNotExistException dnee) {
 1199  0
                         origReqComponentInfo = null;
 1200  0
                     }
 1201  
                 }
 1202  4
                 if (origReqComponentInfo == null) {
 1203  
                     // The reqComponentInfo is a new one so create it
 1204  
                     // the id here even if it is not null it is the temporary ids assigned by client
 1205  
                     // so resets the id to null to allow a new id to be generated.
 1206  4
                     reqComponentInfo.setId(null);
 1207  
                     try {
 1208  4
                         rcAfterInsert = createReqComponent(reqComponentInfo.getType(), reqComponentInfo);
 1209  0
                     } catch (AlreadyExistsException e) {
 1210  
                         // shouldn't happen because of all the check that has been done up to this point
 1211  
                         // if this exception is thrown it should be an error!
 1212  0
                         throw new OperationFailedException("Tried to create a reqComponent that already exists");
 1213  4
                     }
 1214  
                 } else {
 1215  0
                     rcAfterInsert = reqComponentInfo;
 1216  
                 }
 1217  4
                 rcsAfterInserts.add(rcAfterInsert);
 1218  4
             }
 1219  3
             statementTreeViewInfo.setReqComponents(rcsAfterInserts);
 1220  
         }
 1221  
         // check if statementTreeViewInfo already exist if not create it.
 1222  3
         statementId = statementTreeViewInfo.getId();
 1223  3
         if (statementId != null) {
 1224  
             try {
 1225  0
                 origStatementInfo = getStatement(statementId);
 1226  0
             } catch(DoesNotExistException dnee) {
 1227  0
                 origStatementInfo = null;
 1228  0
             }
 1229  
         }
 1230  3
         if (origStatementInfo == null) {
 1231  
             // the id here even if it is not null it is the temporary ids assigned by client
 1232  
             // so resets the id to null to allow a new id to be generated.
 1233  
 //            statementTreeViewInfo.setId(null);
 1234  3
             newStatementInfo = statementAssembler.toStatementInfo(statementTreeViewInfo);
 1235  
             try {
 1236  3
                 newStatementInfo = createStatement(newStatementInfo.getType(), newStatementInfo);
 1237  0
             } catch (AlreadyExistsException e) {
 1238  
                 // shouldn't happen because of all the check that has been done up to this point
 1239  
                 // if this exception is thrown it should be an error!
 1240  0
                 throw new OperationFailedException("Tried to create a statement that already exists");
 1241  3
             }
 1242  3
             statementAssembler.copyValues(statementTreeViewInfo, newStatementInfo);
 1243  
         }
 1244  3
     }
 1245  
 
 1246  
     /**
 1247  
      *
 1248  
      * @return a list of relationships in the first list but not in the second
 1249  
      */
 1250  
         @Override
 1251  
     @Transactional(readOnly=true)
 1252  
         public RefStatementRelationTypeInfo getRefStatementRelationType(final String refStatementRelationTypeKey)
 1253  
                         throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 1254  1
                 checkForNullOrEmptyParameter(refStatementRelationTypeKey, "refStatementRelationTypeKey");
 1255  
 
 1256  1
                 RefStatementRelationType type = this.statementDao.fetch(RefStatementRelationType.class, refStatementRelationTypeKey);
 1257  
 
 1258  1
                 return StatementAssembler.toRefStatementRelationTypeInfo(type);
 1259  
         }
 1260  
 
 1261  
         @Override
 1262  
     @Transactional(readOnly=true)
 1263  
         public List<RefStatementRelationTypeInfo> getRefStatementRelationTypes()
 1264  
                         throws OperationFailedException {
 1265  1
                 List<RefStatementRelationType> entities = this.statementDao.find(RefStatementRelationType.class);
 1266  1
                 return StatementAssembler.toRefStatementRelationTypeInfos(entities);
 1267  
         }
 1268  
 
 1269  
         @Override
 1270  
     @Transactional(readOnly=true)
 1271  
         public List<String> getRefStatementRelationTypesForRefObjectSubType(final String refSubTypeKey)
 1272  
                 throws DoesNotExistException,InvalidParameterException, MissingParameterException, OperationFailedException {
 1273  0
                 throw new UnsupportedOperationException("Method not yet implemented!");
 1274  
         }
 1275  
 
 1276  
         @Override
 1277  
     @Transactional(readOnly=true)
 1278  
         public List<String> getStatementTypesForRefStatementRelationType(final String refStatementRelationTypeKey)
 1279  
                 throws DoesNotExistException, InvalidParameterException, MissingParameterException, OperationFailedException {
 1280  0
                 throw new UnsupportedOperationException("Method not yet implemented!");
 1281  
         }
 1282  
 
 1283  
         public void setValidatorFactory(ValidatorFactory validatorFactory) {
 1284  2
                 this.validatorFactory = validatorFactory;
 1285  2
         }
 1286  
 }