Author: adrianc
Date: Thu Aug 20 23:30:42 2009 New Revision: 806396 URL: http://svn.apache.org/viewvc?rev=806396&view=rev Log: Implemented entity filters. Part of it is commented out - I still need to work out a bug in the EntityListIterator decorator. With this commit, all of the scenarios in the design document have been accommodated. Added: ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareEli.java (with props) ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareIterator.java (with props) ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareList.java (with props) ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareListIterator.java (with props) ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/AccessController.java (with props) ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/util/EntityListIteratorImpl.java (with props) Modified: ofbiz/branches/executioncontext20090812/framework/api/src/org/ofbiz/api/authorization/AccessController.java ofbiz/branches/executioncontext20090812/framework/api/src/org/ofbiz/api/context/ExecutionContext.java ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/AuthorizationManagerImpl.java ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/ExecutionContextImpl.java ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/DelegatorImpl.java ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/ExecutionContext.java ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/datasource/GenericDAO.java ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/model/ModelEntity.java ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/util/EntityListIterator.java ofbiz/branches/executioncontext20090812/framework/example/script/org/ofbiz/example/ExamplePermissionServices.xml ofbiz/branches/executioncontext20090812/framework/example/servicedef/services.xml Modified: ofbiz/branches/executioncontext20090812/framework/api/src/org/ofbiz/api/authorization/AccessController.java URL: http://svn.apache.org/viewvc/ofbiz/branches/executioncontext20090812/framework/api/src/org/ofbiz/api/authorization/AccessController.java?rev=806396&r1=806395&r2=806396&view=diff ============================================================================== --- ofbiz/branches/executioncontext20090812/framework/api/src/org/ofbiz/api/authorization/AccessController.java (original) +++ ofbiz/branches/executioncontext20090812/framework/api/src/org/ofbiz/api/authorization/AccessController.java Thu Aug 20 23:30:42 2009 @@ -20,12 +20,16 @@ import java.security.AccessControlException; import java.security.Permission; +import java.util.List; +import java.util.ListIterator; /** * AccessController interface. */ -public interface AccessController { +public interface AccessController<E> { public void checkPermission(Permission permission) throws AccessControlException; + public List<E> applyFilters(List<E> list); + public ListIterator<E> applyFilters(ListIterator<E> list); } Modified: ofbiz/branches/executioncontext20090812/framework/api/src/org/ofbiz/api/context/ExecutionContext.java URL: http://svn.apache.org/viewvc/ofbiz/branches/executioncontext20090812/framework/api/src/org/ofbiz/api/context/ExecutionContext.java?rev=806396&r1=806395&r2=806396&view=diff ============================================================================== --- ofbiz/branches/executioncontext20090812/framework/api/src/org/ofbiz/api/context/ExecutionContext.java (original) +++ ofbiz/branches/executioncontext20090812/framework/api/src/org/ofbiz/api/context/ExecutionContext.java Thu Aug 20 23:30:42 2009 @@ -32,7 +32,7 @@ * * @return An <code>AccessController</code> instance */ - public AccessController getAccessController(); + public AccessController<?> getAccessController(); /** Returns the currency unit of measure. * Modified: ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/AuthorizationManagerImpl.java URL: http://svn.apache.org/viewvc/ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/AuthorizationManagerImpl.java?rev=806396&r1=806395&r2=806396&view=diff ============================================================================== --- ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/AuthorizationManagerImpl.java (original) +++ ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/AuthorizationManagerImpl.java Thu Aug 20 23:30:42 2009 @@ -22,12 +22,15 @@ import java.security.AccessControlException; import java.security.Permission; +import java.util.List; +import java.util.ListIterator; -import org.ofbiz.api.authorization.AccessController; +import org.ofbiz.entity.AccessController; import org.ofbiz.api.authorization.PermissionsIntersection; import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.UtilMisc; import org.ofbiz.base.util.UtilProperties; +import org.ofbiz.entity.util.EntityListIterator; import org.ofbiz.security.AuthorizationManager; import org.ofbiz.security.OFBizSecurity; import org.ofbiz.service.ExecutionContext; @@ -37,7 +40,11 @@ * An implementation of the AuthorizationManager interface that uses the OFBiz database * for authorization data storage. */ -public class AuthorizationManagerImpl extends OFBizSecurity implements AuthorizationManager { +public class AuthorizationManagerImpl<E> extends OFBizSecurity implements AuthorizationManager { + + // Right now this class is being used as a test jig for the various classes + // it will be working with. The actual implementation will occur once the + // entities are defined and in place. public static final String module = AuthorizationManagerImpl.class.getName(); @@ -129,19 +136,22 @@ } - public AccessController getAccessController(org.ofbiz.api.context.ExecutionContext executionContext) { - return new AccessControllerImpl(executionContext.getExecutionPath(), this.getTestPermission((ExecutionContext) executionContext)); + public AccessController<E> getAccessController(org.ofbiz.api.context.ExecutionContext executionContext) { + return new AccessControllerImpl<E>((ExecutionContext) executionContext, this.getTestPermission((ExecutionContext) executionContext)); } - protected static class AccessControllerImpl implements AccessController { + protected static class AccessControllerImpl<E> implements AccessController<E> { - protected final String executionPath; + protected final ExecutionContext executionContext; + protected final String executionPath; protected final Permission permission; // Temporary - will be removed later protected boolean verbose = false; + protected List<String> serviceNameList = UtilMisc.toList("securityRedesignTest"); - protected AccessControllerImpl(String executionPath, Permission permission) { - this.executionPath = executionPath; + protected AccessControllerImpl(ExecutionContext executionContext, Permission permission) { + this.executionContext = executionContext; + this.executionPath = executionContext.getExecutionPath(); this.permission = permission; this.verbose = "true".equals(UtilProperties.getPropertyValue("api.properties", "authorizationManager.verbose")); } @@ -154,7 +164,40 @@ throw new AccessControlException(this.executionPath); } } - + + public List<E> applyFilters(List<E> list) { + String upperPath = this.executionPath.toUpperCase(); + if (upperPath.startsWith("OFBIZ/EXAMPLE")) { + if (this.verbose) { + Debug.logInfo("Applying List filter \"securityRedesignTest\" for path " + this.executionPath, module); + } + return new SecurityAwareList<E>(list, this.serviceNameList, this.executionContext); + } + return list; + } + + public ListIterator<E> applyFilters(ListIterator<E> listIterator) { + String upperPath = this.executionPath.toUpperCase(); + if (upperPath.startsWith("OFBIZ/EXAMPLE")) { + if (this.verbose) { + Debug.logInfo("Applying ListIterator filter \"securityRedesignTest\" for path " + this.executionPath, module); + } + return new SecurityAwareListIterator<E>(listIterator, this.serviceNameList, this.executionContext); + } + return listIterator; + } + + public EntityListIterator applyFilters(EntityListIterator listIterator) { + String upperPath = this.executionPath.toUpperCase(); + if (upperPath.startsWith("OFBIZ/EXAMPLE")) { + if (this.verbose) { + Debug.logInfo("Applying EntityListIterator filter \"securityRedesignTest\" for path " + this.executionPath, module); + } + // Commented out for now - causes problems with list pagination in UI +// return new SecurityAwareEli(listIterator, this.serviceNameList, this.executionContext); + } + return listIterator; + } } } Modified: ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/ExecutionContextImpl.java URL: http://svn.apache.org/viewvc/ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/ExecutionContextImpl.java?rev=806396&r1=806395&r2=806396&view=diff ============================================================================== --- ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/ExecutionContextImpl.java (original) +++ ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/ExecutionContextImpl.java Thu Aug 20 23:30:42 2009 @@ -22,7 +22,7 @@ import java.util.Map; import java.util.TimeZone; -import org.ofbiz.api.authorization.AccessController; +import org.ofbiz.entity.AccessController; import org.ofbiz.entity.DelegatorFactory; import org.ofbiz.entity.GenericDelegator; import org.ofbiz.entity.GenericValue; @@ -102,7 +102,7 @@ } } - public AccessController getAccessController() { - return this.getSecurity().getAccessController(this); + public AccessController<?> getAccessController() { + return (AccessController<?>) this.getSecurity().getAccessController(this); } } Added: ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareEli.java URL: http://svn.apache.org/viewvc/ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareEli.java?rev=806396&view=auto ============================================================================== --- ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareEli.java (added) +++ ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareEli.java Thu Aug 20 23:30:42 2009 @@ -0,0 +1,147 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + *******************************************************************************/ +package org.ofbiz.context; + +import java.util.List; + +import javolution.util.FastList; + +import org.ofbiz.entity.GenericDelegator; +import org.ofbiz.entity.GenericEntityException; +import org.ofbiz.entity.GenericValue; +import org.ofbiz.entity.util.EntityListIterator; +import org.ofbiz.service.ExecutionContext; + +/** + * SecurityAwareEli class. This class decorates an <code> + * EntityListIterator</code> instance and filters a list of + * <code>GenericValue</code>s based on a set of permission services. + * <p>The permission service must implement <code>permissionInterface</code> + * and accept an optional <code>candidateObject</code> parameter (parameter + * type is <code>java.lang.Object</code>). The service should + * return <code>hasPermission = true</code> if the user is granted access + * to the <code>candidateObject</code>.</p> + */ +public class SecurityAwareEli extends SecurityAwareListIterator<GenericValue> implements EntityListIterator { + + public static final String module = SecurityAwareEli.class.getName(); + protected final EntityListIterator listIterator; + protected GenericValue previousValue = null; + + public SecurityAwareEli(EntityListIterator iterator, List<String> serviceNameList, ExecutionContext executionContext) { + super(iterator, serviceNameList, executionContext); + this.listIterator = iterator; + } + + public boolean absolute(int rowNum) throws GenericEntityException { + return this.listIterator.absolute(rowNum); + } + + public void afterLast() throws GenericEntityException { + this.listIterator.afterLast(); + } + + public void beforeFirst() throws GenericEntityException { + this.listIterator.beforeFirst(); + } + + public void close() throws GenericEntityException { + this.listIterator.close(); + } + + public GenericValue currentGenericValue() throws GenericEntityException { + GenericValue value = this.listIterator.currentGenericValue(); + while (value != null && !this.hasPermission(value)) { + value = this.next(); + } + return value; + } + + public int currentIndex() throws GenericEntityException { + return this.listIterator.currentIndex(); + } + + public boolean first() throws GenericEntityException { + return this.listIterator.first(); + } + + public List<GenericValue> getCompleteList() throws GenericEntityException { + List<GenericValue> list = FastList.newInstance(); + GenericValue nextValue = this.next(); + while (nextValue != null) { + list.add(nextValue); + nextValue = this.next(); + } + return list; + } + + public List<GenericValue> getPartialList(int start, int number) throws GenericEntityException { + List<GenericValue> list = FastList.newInstance(); + if (number == 0) { + return list; + } + if (start == 0) { + start = 1; + } + GenericValue nextValue = null; + if (start == 1) { + nextValue = this.next(); + if (nextValue == null) { + return list; + } + } else { + nextValue = this.getAbsolute(start); + } + int numRetreived = 1; + while (number > numRetreived && nextValue != null) { + list.add(nextValue); + numRetreived++; + nextValue = this.next(); + } + return list; + } + + protected GenericValue getAbsolute(int start) throws GenericEntityException { + if (!this.absolute(start)) { + return null; + } + return this.currentGenericValue(); + } + + public int getResultsSizeAfterPartialList() throws GenericEntityException { + return this.listIterator.getResultsSizeAfterPartialList(); + } + + public boolean last() throws GenericEntityException { + return this.listIterator.last(); + } + + public boolean relative(int rows) throws GenericEntityException { + return this.listIterator.relative(rows); + } + + public void setDelegator(GenericDelegator delegator) { + this.listIterator.setDelegator(delegator); + } + + public void setFetchSize(int rows) throws GenericEntityException { + this.listIterator.setFetchSize(rows); + } + +} Propchange: ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareEli.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareEli.java ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareEli.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareIterator.java URL: http://svn.apache.org/viewvc/ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareIterator.java?rev=806396&view=auto ============================================================================== --- ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareIterator.java (added) +++ ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareIterator.java Thu Aug 20 23:30:42 2009 @@ -0,0 +1,128 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + *******************************************************************************/ +package org.ofbiz.context; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javolution.util.FastMap; + +import org.ofbiz.base.util.Debug; +import org.ofbiz.service.ExecutionContext; +import org.ofbiz.service.LocalDispatcher; +import org.ofbiz.service.DispatchContext; +import org.ofbiz.service.ModelService; + +/** + * SecurityAwareIterator class. This class decorates an <code> + * Iterator</code> instance and filters a list of + * <code>Object</code>s based on a set of permission services. + * <p>The permission service must implement <code>permissionInterface</code> + * and accept an optional <code>candidateObject</code> parameter (parameter + * type is <code>java.lang.Object</code>). The service should + * return <code>hasPermission = true</code> if the user is granted access + * to the <code>candidateObject</code>.</p> + */ +public class SecurityAwareIterator<E> implements Iterator<E> { + + public static final String module = SecurityAwareIterator.class.getName(); + protected final Iterator<E> iterator; + protected final List<String> serviceNameList; + protected final ExecutionContext executionContext; + protected E nextValue = null; + + public SecurityAwareIterator(Iterator<E> iterator, List<String> serviceNameList, ExecutionContext executionContext) { + this.iterator = iterator; + this.serviceNameList = serviceNameList; + this.executionContext = executionContext; + getNext(); + } + + protected void getNext() { + // Unusual loop for EntityListIterator compatibility + E value = null; + try { + value = this.iterator.next(); + } catch (Exception e) {} + while (value != null) { + if (this.hasPermission(value)) { + this.nextValue = value; + return; + } + value = null; + try { + value = this.iterator.next(); + } catch (Exception e) {} + } + } + + public boolean hasNext() { + return this.nextValue != null; + } + + public E next() { + E value = this.nextValue; + this.nextValue = null; + this.getNext(); + return value; + } + + public void remove() { + this.iterator.remove(); + } + + protected boolean hasPermission(E value) { + if (this.executionContext.getUserLogin() == null) { + // This is here for development purposes + return true; + } + try { + LocalDispatcher dispatcher = this.executionContext.getDispatcher(); + DispatchContext ctx = dispatcher.getDispatchContext(); + Map<String, ? extends Object> params = this.executionContext.getParameters(); + for (String serviceName : this.serviceNameList) { + ModelService modelService = ctx.getModelService(serviceName); + Map<String, Object> context = FastMap.newInstance(); + if (params != null) { + context.putAll(params); + } + if (!context.containsKey("userLogin")) { + context.put("userLogin", this.executionContext.getUserLogin()); + } + if (!context.containsKey("locale")) { + context.put("locale", this.executionContext.getLocale()); + } + if (!context.containsKey("timeZone")) { + context.put("timeZone", this.executionContext.getTimeZone()); + } + context.put("candidateObject", value); + context = modelService.makeValid(context, ModelService.IN_PARAM); + Map<String, Object> result = dispatcher.runSync(serviceName, context); + Boolean hasPermission = (Boolean) result.get("hasPermission"); + if (hasPermission != null && !hasPermission.booleanValue()) { + return false; + } + } + } catch (Exception e) { + Debug.logError(e, module); + } + return true; + } +} Propchange: ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareIterator.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareIterator.java ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareIterator.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareList.java URL: http://svn.apache.org/viewvc/ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareList.java?rev=806396&view=auto ============================================================================== --- ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareList.java (added) +++ ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareList.java Thu Aug 20 23:30:42 2009 @@ -0,0 +1,55 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + *******************************************************************************/ +package org.ofbiz.context; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; + +import org.ofbiz.service.ExecutionContext; + +/** + * SecurityAwareList class. + */ +@SuppressWarnings("serial") +public class SecurityAwareList<E> extends ArrayList<E> implements List<E> { + + protected final static String module = SecurityAwareList.class.getName(); + protected final List<String> serviceNameList; + protected final ExecutionContext executionContext; + + public SecurityAwareList(List<E> valueList, List<String> serviceNameList, ExecutionContext executionContext) { + super(valueList.size()); + this.addAll(valueList); + this.trimToSize(); + this.serviceNameList = serviceNameList; + this.executionContext = executionContext; + } + + @Override + public Iterator<E> iterator() { + return new SecurityAwareIterator<E>(super.iterator(), this.serviceNameList, this.executionContext); + } + + @Override + public ListIterator<E> listIterator() { + return new SecurityAwareListIterator<E>(super.listIterator(), this.serviceNameList, this.executionContext); + } +} Propchange: ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareList.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareList.java ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareList.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareListIterator.java URL: http://svn.apache.org/viewvc/ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareListIterator.java?rev=806396&view=auto ============================================================================== --- ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareListIterator.java (added) +++ ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareListIterator.java Thu Aug 20 23:30:42 2009 @@ -0,0 +1,101 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + *******************************************************************************/ +package org.ofbiz.context; + +import java.util.List; +import java.util.ListIterator; + +import org.ofbiz.service.ExecutionContext; + +/** + * SecurityAwareListIterator class. This class decorates a <code> + * ListIterator</code> instance and filters a list of + * <code>GenericValue</code>s based on a set of permission services. + * <p>The permission service must implement <code>permissionInterface</code> + * and accept an optional <code>candidateObject</code> parameter (parameter + * type is <code>java.lang.Object</code>). The service should + * return <code>hasPermission = true</code> if the user is granted access + * to the <code>candidateObject</code>.</p> + */ +public class SecurityAwareListIterator<E> extends SecurityAwareIterator<E> implements ListIterator<E> { + + public static final String module = SecurityAwareListIterator.class.getName(); + protected final ListIterator<E> listIterator; + protected E previousValue = null; + protected int index = 0; + + public SecurityAwareListIterator(ListIterator<E> iterator, List<String> serviceNameList, ExecutionContext executionContext) { + super(iterator, serviceNameList, executionContext); + this.listIterator = iterator; + } + + protected void getPrevious() { + // Unusual loop for EntityListIterator compatibility + E value = null; + try { + value = this.listIterator.previous(); + } catch (Exception e) {} + while (value != null) { + if (this.hasPermission(value)) { + this.index--; + this.previousValue = value; + return; + } + value = null; + try { + value = this.listIterator.previous(); + } catch (Exception e) {} + } + } + + public E next() { + E value = super.next(); + if (value != null) { + this.index++; + } + return value; + } + + public void add(E o) { + this.listIterator.add(o); + } + + public boolean hasPrevious() { + return this.previousValue != null; + } + + public int nextIndex() { + return this.index + 1; + } + + public E previous() { + E value = this.previousValue; + this.previousValue = null; + this.getPrevious(); + return value; + } + + public int previousIndex() { + return this.index - 1; + } + + public void set(E o) { + this.listIterator.set(o); + } +} Propchange: ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareListIterator.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareListIterator.java ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/branches/executioncontext20090812/framework/context/src/org/ofbiz/context/SecurityAwareListIterator.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Added: ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/AccessController.java URL: http://svn.apache.org/viewvc/ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/AccessController.java?rev=806396&view=auto ============================================================================== --- ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/AccessController.java (added) +++ ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/AccessController.java Thu Aug 20 23:30:42 2009 @@ -0,0 +1,33 @@ +/******************************************************************************* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + *******************************************************************************/ +package org.ofbiz.entity; + +import org.ofbiz.entity.util.EntityListIterator; + +/** + * AccessController interface. This interface extends <code> + * org.ofbiz.api.authorization.AccessController</code> so that + * the <code>applyFilters</code> method can be overridden to handle + * <code>EntityListIterator</code>. + */ +public interface AccessController<E> extends org.ofbiz.api.authorization.AccessController<E> { + + public EntityListIterator applyFilters(EntityListIterator listIterator); + +} Propchange: ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/AccessController.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/AccessController.java ------------------------------------------------------------------------------ svn:keywords = "Date Rev Author URL Id" Propchange: ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/AccessController.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/DelegatorImpl.java URL: http://svn.apache.org/viewvc/ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/DelegatorImpl.java?rev=806396&r1=806395&r2=806396&view=diff ============================================================================== --- ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/DelegatorImpl.java (original) +++ ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/DelegatorImpl.java Thu Aug 20 23:30:42 2009 @@ -36,7 +36,6 @@ import javolution.util.FastList; import javolution.util.FastMap; -import org.ofbiz.api.authorization.AccessController; import static org.ofbiz.api.authorization.BasicPermissions.*; import org.ofbiz.api.context.GenericExecutionArtifact; import org.ofbiz.base.util.Debug; @@ -369,7 +368,7 @@ public GenericValue create(GenericValue value, boolean doCacheClear) throws GenericEntityException { this.executionContext.pushExecutionArtifact(value); - AccessController accessController = this.executionContext.getAccessController(); + AccessController<?> accessController = this.executionContext.getAccessController(); boolean beganTransaction = false; try { accessController.checkPermission(Create); @@ -523,7 +522,7 @@ public GenericValue createOrStore(GenericValue value, boolean doCacheClear) throws GenericEntityException { this.executionContext.pushExecutionArtifact(value); - AccessController accessController = this.executionContext.getAccessController(); + AccessController<?> accessController = this.executionContext.getAccessController(); boolean beganTransaction = false; try { GenericValue checkValue = this.findOne(value.getEntityName(), value.getPrimaryKey(), false); @@ -780,6 +779,10 @@ eli.setDelegator(this); ecaRunner.evalRules(EntityEcaHandler.EV_RETURN, EntityEcaHandler.OP_FIND, dummyValue, false); + this.executionContext.pushExecutionArtifact(modelEntity); + AccessController<?> accessController = this.executionContext.getAccessController(); + eli = accessController.applyFilters(eli); + this.executionContext.popExecutionArtifact(); return eli; } @@ -832,6 +835,8 @@ } this.decryptFields(results); + AccessController<GenericValue> accessController = (AccessController<GenericValue>) this.executionContext.getAccessController(); + results = accessController.applyFilters(results); return results; } catch (GenericEntityException e) { String errMsg = "Failure in findAllByPrimaryKeys operation, rolling back transaction"; @@ -899,6 +904,8 @@ } this.decryptFields(results); + AccessController<GenericValue> accessController = (AccessController<GenericValue>) this.executionContext.getAccessController(); + results = accessController.applyFilters(results); return results; } catch (GenericEntityException e) { String errMsg = "Failure in findAllByPrimaryKeysCache operation, rolling back transaction"; @@ -984,6 +991,10 @@ EntityListIterator eli = this.find(entityName, whereEntityCondition, havingEntityCondition, UtilMisc.toSet(fieldsToSelect), orderBy, findOptions); eli.setDelegator(this); + this.executionContext.pushExecutionArtifact(new GenericExecutionArtifact("GenericDelegator.findByCondition", entityName)); + AccessController<GenericValue> accessController = (AccessController<GenericValue>) this.executionContext.getAccessController(); + eli = accessController.applyFilters(eli); + this.executionContext.popExecutionArtifact(); List<GenericValue> list = eli.getCompleteList(); eli.close(); @@ -1229,6 +1240,10 @@ List<GenericValue> cacheList = this.delegatorData.cache.get(entityName, entityCondition, orderBy); if (cacheList != null) { + this.executionContext.pushExecutionArtifact(new GenericExecutionArtifact("GenericDelegator.findList", entityName)); + AccessController<GenericValue> accessController = (AccessController<GenericValue>) this.executionContext.getAccessController(); + cacheList = accessController.applyFilters(cacheList); + this.executionContext.popExecutionArtifact(); return cacheList; } } @@ -1248,6 +1263,10 @@ ecaRunner.evalRules(EntityEcaHandler.EV_CACHE_PUT, EntityEcaHandler.OP_FIND, dummyValue, false); this.delegatorData.cache.put(entityName, entityCondition, orderBy, list); } + this.executionContext.pushExecutionArtifact(new GenericExecutionArtifact("GenericDelegator.findList", entityName)); + AccessController<GenericValue> accessController = (AccessController<GenericValue>) this.executionContext.getAccessController(); + list = accessController.applyFilters(list); + this.executionContext.popExecutionArtifact(); return list; } catch (GenericEntityException e) { String errMsg = "Failure in findByCondition operation for entity [" + entityName + "]: " + e.toString() + ". Rolling back transaction."; @@ -1293,6 +1312,10 @@ EntityListIterator eli = helper.findListIteratorByCondition(modelViewEntity, whereEntityCondition, havingEntityCondition, fieldsToSelect, orderBy, findOptions); eli.setDelegator(this); // TODO: add decrypt fields + this.executionContext.pushExecutionArtifact(new GenericExecutionArtifact("GenericDelegator.findListIteratorByCondition", modelViewEntity.getEntityName())); + AccessController<GenericValue> accessController = (AccessController<GenericValue>) this.executionContext.getAccessController(); + eli = accessController.applyFilters(eli); + this.executionContext.popExecutionArtifact(); return eli; } @@ -2160,7 +2183,7 @@ public int removeByCondition(String entityName, EntityCondition condition, boolean doCacheClear) throws GenericEntityException { this.executionContext.pushExecutionArtifact(new GenericExecutionArtifact("GenericDelegator.removeByCondition", entityName)); - AccessController accessController = this.executionContext.getAccessController(); + AccessController<?> accessController = this.executionContext.getAccessController(); boolean beganTransaction = false; try { accessController.checkPermission(Delete); @@ -2215,7 +2238,7 @@ public int removeByPrimaryKey(GenericPK primaryKey, boolean doCacheClear) throws GenericEntityException { this.executionContext.pushExecutionArtifact(primaryKey); - AccessController accessController = this.executionContext.getAccessController(); + AccessController<?> accessController = this.executionContext.getAccessController(); boolean beganTransaction = false; try { accessController.checkPermission(Delete); @@ -2302,7 +2325,7 @@ public int removeValue(GenericValue value, boolean doCacheClear) throws GenericEntityException { this.executionContext.pushExecutionArtifact(value); - AccessController accessController = this.executionContext.getAccessController(); + AccessController<?> accessController = this.executionContext.getAccessController(); // NOTE: this does not call the GenericDelegator.removeByPrimaryKey // method because it has more information to pass to the ECA rule hander boolean beganTransaction = false; @@ -2530,7 +2553,7 @@ public int store(GenericValue value, boolean doCacheClear) throws GenericEntityException { this.executionContext.pushExecutionArtifact(value); - AccessController accessController = this.executionContext.getAccessController(); + AccessController<?> accessController = this.executionContext.getAccessController(); boolean beganTransaction = false; try { accessController.checkPermission(Update); @@ -2694,7 +2717,7 @@ public int storeByCondition(String entityName, Map<String, ? extends Object> fieldsToSet, EntityCondition condition, boolean doCacheClear) throws GenericEntityException { this.executionContext.pushExecutionArtifact(new GenericExecutionArtifact("GenericDelegator.storeByCondition", entityName)); - AccessController accessController = this.executionContext.getAccessController(); + AccessController<?> accessController = this.executionContext.getAccessController(); boolean beganTransaction = false; try { accessController.checkPermission(Update); Modified: ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/ExecutionContext.java URL: http://svn.apache.org/viewvc/ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/ExecutionContext.java?rev=806396&r1=806395&r2=806396&view=diff ============================================================================== --- ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/ExecutionContext.java (original) +++ ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/ExecutionContext.java Thu Aug 20 23:30:42 2009 @@ -24,6 +24,8 @@ */ public interface ExecutionContext extends org.ofbiz.api.context.ExecutionContext { + public AccessController<?> getAccessController(); + /** Returns the current <code>GenericDelegator</code> instance. * * @return The current <code>GenericDelegator</code> instance Modified: ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/datasource/GenericDAO.java URL: http://svn.apache.org/viewvc/ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/datasource/GenericDAO.java?rev=806396&r1=806395&r2=806396&view=diff ============================================================================== --- ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/datasource/GenericDAO.java (original) +++ ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/datasource/GenericDAO.java Thu Aug 20 23:30:42 2009 @@ -53,6 +53,7 @@ import org.ofbiz.entity.transaction.TransactionUtil; import org.ofbiz.entity.util.EntityFindOptions; import org.ofbiz.entity.util.EntityListIterator; +import org.ofbiz.entity.util.EntityListIteratorImpl; /** * Generic Entity Data Access Object - Handles persistence for any defined entity. @@ -758,7 +759,7 @@ Debug.logTiming("Ran query in " + queryTotalTime + " milli-seconds: " + sql, module); } } - return new EntityListIterator(sqlP, modelEntity, selectFields, modelFieldTypeReader); + return new EntityListIteratorImpl(sqlP, modelEntity, selectFields, modelFieldTypeReader); } protected StringBuilder makeConditionWhereString(ModelEntity modelEntity, EntityCondition whereEntityCondition, List<EntityCondition> viewWhereConditions, List<EntityConditionParam> whereEntityConditionParams) throws GenericEntityException { Modified: ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/model/ModelEntity.java URL: http://svn.apache.org/viewvc/ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/model/ModelEntity.java?rev=806396&r1=806395&r2=806396&view=diff ============================================================================== --- ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/model/ModelEntity.java (original) +++ ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/model/ModelEntity.java Thu Aug 20 23:30:42 2009 @@ -33,6 +33,7 @@ import javolution.util.FastList; import javolution.util.FastMap; +import org.ofbiz.api.context.ExecutionArtifact; import org.ofbiz.base.util.Debug; import org.ofbiz.base.util.GeneralException; import org.ofbiz.base.util.ObjectType; @@ -56,7 +57,7 @@ * */ @SuppressWarnings("serial") -public class ModelEntity extends ModelInfo implements Comparable<ModelEntity>, Serializable { +public class ModelEntity extends ModelInfo implements Comparable<ModelEntity>, Serializable, ExecutionArtifact { public static final String module = ModelEntity.class.getName(); @@ -1600,4 +1601,8 @@ return topLevelMap; } + + public String getName() { + return this.entityName; + } } Modified: ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/util/EntityListIterator.java URL: http://svn.apache.org/viewvc/ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/util/EntityListIterator.java?rev=806396&r1=806395&r2=806396&view=diff ============================================================================== --- ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/util/EntityListIterator.java (original) +++ ofbiz/branches/executioncontext20090812/framework/entity/src/org/ofbiz/entity/util/EntityListIterator.java Thu Aug 20 23:30:42 2009 @@ -1,525 +1,58 @@ -/******************************************************************************* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - *******************************************************************************/ - package org.ofbiz.entity.util; - -import java.sql.ResultSet; -import java.sql.SQLException; import java.util.List; import java.util.ListIterator; -import javolution.util.FastList; - -import org.ofbiz.base.util.Debug; -import org.ofbiz.base.util.GeneralRuntimeException; import org.ofbiz.entity.GenericDelegator; import org.ofbiz.entity.GenericEntityException; -import org.ofbiz.entity.GenericResultSetClosedException; import org.ofbiz.entity.GenericValue; -import org.ofbiz.entity.jdbc.SQLProcessor; -import org.ofbiz.entity.jdbc.SqlJdbcUtil; -import org.ofbiz.entity.model.ModelEntity; -import org.ofbiz.entity.model.ModelField; -import org.ofbiz.entity.model.ModelFieldTypeReader; - - -/** - * Generic Entity Cursor List Iterator for Handling Cursored DB Results - */ -public class EntityListIterator implements ListIterator<GenericValue> { - - /** Module Name Used for debugging */ - public static final String module = EntityListIterator.class.getName(); - - protected SQLProcessor sqlp; - protected ResultSet resultSet; - protected ModelEntity modelEntity; - protected List<ModelField> selectFields; - protected ModelFieldTypeReader modelFieldTypeReader; - protected boolean closed = false; - protected boolean haveMadeValue = false; - protected GenericDelegator delegator = null; - - private boolean haveShowHasNextWarning = false; - - public EntityListIterator(SQLProcessor sqlp, ModelEntity modelEntity, List<ModelField> selectFields, ModelFieldTypeReader modelFieldTypeReader) { - this.sqlp = sqlp; - this.resultSet = sqlp.getResultSet(); - this.modelEntity = modelEntity; - this.selectFields = selectFields; - this.modelFieldTypeReader = modelFieldTypeReader; - } - - public EntityListIterator(ResultSet resultSet, ModelEntity modelEntity, List<ModelField> selectFields, ModelFieldTypeReader modelFieldTypeReader) { - this.sqlp = null; - this.resultSet = resultSet; - this.modelEntity = modelEntity; - this.selectFields = selectFields; - this.modelFieldTypeReader = modelFieldTypeReader; - } - - public void setDelegator(GenericDelegator delegator) { - this.delegator = delegator; - } + +public interface EntityListIterator extends ListIterator<GenericValue> { + + public void setDelegator(GenericDelegator delegator); /** Sets the cursor position to just after the last result so that previous() will return the last result */ - public void afterLast() throws GenericEntityException { - try { - resultSet.afterLast(); - } catch (SQLException e) { - if (!closed) { - this.close(); - Debug.logWarning("Warning: auto-closed EntityListIterator because of exception: " + e.toString(), module); - } - throw new GenericEntityException("Error setting the cursor to afterLast", e); - } - } + public void afterLast() throws GenericEntityException; /** Sets the cursor position to just before the first result so that next() will return the first result */ - public void beforeFirst() throws GenericEntityException { - try { - resultSet.beforeFirst(); - } catch (SQLException e) { - if (!closed) { - this.close(); - Debug.logWarning("Warning: auto-closed EntityListIterator because of exception: " + e.toString(), module); - } - throw new GenericEntityException("Error setting the cursor to beforeFirst", e); - } - } + public void beforeFirst() throws GenericEntityException; /** Sets the cursor position to last result; if result set is empty returns false */ - public boolean last() throws GenericEntityException { - try { - return resultSet.last(); - } catch (SQLException e) { - if (!closed) { - this.close(); - Debug.logWarning("Warning: auto-closed EntityListIterator because of exception: " + e.toString(), module); - } - throw new GenericEntityException("Error setting the cursor to last", e); - } - } + public boolean last() throws GenericEntityException; /** Sets the cursor position to last result; if result set is empty returns false */ - public boolean first() throws GenericEntityException { - try { - return resultSet.first(); - } catch (SQLException e) { - if (!closed) { - this.close(); - Debug.logWarning("Warning: auto-closed EntityListIterator because of exception: " + e.toString(), module); - } - throw new GenericEntityException("Error setting the cursor to first", e); - } - } - - public void close() throws GenericEntityException { - if (closed) { - //maybe not the best way: throw new GenericResultSetClosedException("This EntityListIterator has been closed, this operation cannot be performed"); - Debug.logWarning("This EntityListIterator for Entity [" + modelEntity==null?"":modelEntity.getEntityName() + "] has already been closed, not closing again.", module); - } else { - if (sqlp != null) { - sqlp.close(); - closed = true; - } else if (resultSet != null) { - try { - resultSet.close(); - } catch (SQLException e) { - throw new GenericEntityException("Cannot close EntityListIterator with ResultSet", e); - } - closed = true; - } else { - throw new GenericEntityException("Cannot close an EntityListIterator without a SQLProcessor or a ResultSet"); - } - } - } - - /** NOTE: Calling this method does return the current value, but so does calling next() or previous(), so calling one of those AND this method will cause the value to be created twice */ - public GenericValue currentGenericValue() throws GenericEntityException { - if (closed) throw new GenericResultSetClosedException("This EntityListIterator has been closed, this operation cannot be performed"); + public boolean first() throws GenericEntityException; - GenericValue value = GenericValue.create(modelEntity); + public void close() throws GenericEntityException; - for (int j = 0; j < selectFields.size(); j++) { - ModelField curField = selectFields.get(j); + /** NOTE: Calling this method does return the current value, but so does calling next() or previous(), so calling one of those AND this method will cause the value to be created twice */ + public GenericValue currentGenericValue() throws GenericEntityException; - SqlJdbcUtil.getValue(resultSet, j + 1, curField, value, modelFieldTypeReader); - } - - value.setDelegator(this.delegator); - value.synchronizedWithDatasource(); - this.haveMadeValue = true; - if (delegator != null) { - delegator.decryptFields(value); - } - return value; - } - - public int currentIndex() throws GenericEntityException { - if (closed) throw new GenericResultSetClosedException("This EntityListIterator has been closed, this operation cannot be performed"); - - try { - return resultSet.getRow(); - } catch (SQLException e) { - if (!closed) { - this.close(); - Debug.logWarning("Warning: auto-closed EntityListIterator because of exception: " + e.toString(), module); - } - throw new GenericEntityException("Error getting the current index", e); - } - } + public int currentIndex() throws GenericEntityException; /** performs the same function as the ResultSet.absolute method; * if rowNum is positive, goes to that position relative to the beginning of the list; * if rowNum is negative, goes to that position relative to the end of the list; * a rowNum of 1 is the same as first(); a rowNum of -1 is the same as last() */ - public boolean absolute(int rowNum) throws GenericEntityException { - if (closed) throw new GenericResultSetClosedException("This EntityListIterator has been closed, this operation cannot be performed"); - - try { - return resultSet.absolute(rowNum); - } catch (SQLException e) { - if (!closed) { - this.close(); - Debug.logWarning("Warning: auto-closed EntityListIterator because of exception: " + e.toString(), module); - } - throw new GenericEntityException("Error setting the absolute index to " + rowNum, e); - } - } + public boolean absolute(int rowNum) throws GenericEntityException; /** performs the same function as the ResultSet.relative method; * if rows is positive, goes forward relative to the current position; * if rows is negative, goes backward relative to the current position; */ - public boolean relative(int rows) throws GenericEntityException { - if (closed) throw new GenericResultSetClosedException("This EntityListIterator has been closed, this operation cannot be performed"); + public boolean relative(int rows) throws GenericEntityException; - try { - return resultSet.relative(rows); - } catch (SQLException e) { - if (!closed) { - this.close(); - Debug.logWarning("Warning: auto-closed EntityListIterator because of exception: " + e.toString(), module); - } - throw new GenericEntityException("Error going to the relative index " + rows, e); - } - } - - /** - * PLEASE NOTE: Because of the nature of the JDBC ResultSet interface this method can be very inefficient; it is much better to just use next() until it returns null - * For example, you could use the following to iterate through the results in an EntityListIterator: - * - * GenericValue nextValue = null; - * while ((nextValue = (GenericValue) this.next()) != null) { ... } - * - */ - public boolean hasNext() { - if (!haveShowHasNextWarning) { - // DEJ20050207 To further discourage use of this, and to find existing use, always log a big warning showing where it is used: - Exception whereAreWe = new Exception(); - Debug.logWarning(whereAreWe, "WARNING: For performance reasons do not use the EntityListIterator.hasNext() method, just call next() until it returns null; see JavaDoc comments in the EntityListIterator class for details and an example", module); - - haveShowHasNextWarning = true; - } - - try { - if (resultSet.isLast() || resultSet.isAfterLast()) { - return false; - } else { - // do a quick game to see if the resultSet is empty: - // if we are not in the first or beforeFirst positions and we haven't made any values yet, the result set is empty so return false - if (!haveMadeValue && !resultSet.isBeforeFirst() && !resultSet.isFirst()) { - return false; - } else { - return true; - } - } - } catch (SQLException e) { - if (!closed) { - try { - this.close(); - } catch (GenericEntityException e1) { - Debug.logError(e1, "Error auto-closing EntityListIterator on error, so info below for more info on original error; close error: " + e1.toString(), module); - } - Debug.logWarning("Warning: auto-closed EntityListIterator because of exception: " + e.toString(), module); - } - throw new GeneralRuntimeException("Error while checking to see if this is the last result", e); - } - } - - /** PLEASE NOTE: Because of the nature of the JDBC ResultSet interface this method can be very inefficient; it is much better to just use previous() until it returns null */ - public boolean hasPrevious() { - try { - if (resultSet.isFirst() || resultSet.isBeforeFirst()) { - return false; - } else { - // do a quick game to see if the resultSet is empty: - // if we are not in the last or afterLast positions and we haven't made any values yet, the result set is empty so return false - if (!haveMadeValue && !resultSet.isAfterLast() && !resultSet.isLast()) { - return false; - } else { - return true; - } - } - } catch (SQLException e) { - if (!closed) { - try { - this.close(); - } catch (GenericEntityException e1) { - Debug.logError(e1, "Error auto-closing EntityListIterator on error, so info below for more info on original error; close error: " + e1.toString(), module); - } - Debug.logWarning("Warning: auto-closed EntityListIterator because of exception: " + e.toString(), module); - } - throw new GeneralRuntimeException("Error while checking to see if this is the first result", e); - } - } - - /** Moves the cursor to the next position and returns the GenericValue object for that position; if there is no next, returns null - * For example, you could use the following to iterate through the results in an EntityListIterator: - * - * GenericValue nextValue = null; - * while ((nextValue = (GenericValue) this.next()) != null) { ... } - * - */ - public GenericValue next() { - try { - if (resultSet.next()) { - return currentGenericValue(); - } else { - return null; - } - } catch (SQLException e) { - if (!closed) { - try { - this.close(); - } catch (GenericEntityException e1) { - Debug.logError(e1, "Error auto-closing EntityListIterator on error, so info below for more info on original error; close error: " + e1.toString(), module); - } - Debug.logWarning("Warning: auto-closed EntityListIterator because of exception: " + e.toString(), module); - } - throw new GeneralRuntimeException("Error getting the next result", e); - } catch (GenericEntityException e) { - if (!closed) { - try { - this.close(); - } catch (GenericEntityException e1) { - Debug.logError(e1, "Error auto-closing EntityListIterator on error, so info below for more info on original error; close error: " + e1.toString(), module); - } - Debug.logWarning("Warning: auto-closed EntityListIterator because of exception: " + e.toString(), module); - } - throw new GeneralRuntimeException("Error creating GenericValue", e); - } - } - - /** Returns the index of the next result, but does not guarantee that there will be a next result */ - public int nextIndex() { - try { - return currentIndex() + 1; - } catch (GenericEntityException e) { - if (!closed) { - try { - this.close(); - } catch (GenericEntityException e1) { - Debug.logError(e1, "Error auto-closing EntityListIterator on error, so info below for more info on original error; close error: " + e1.toString(), module); - } - Debug.logWarning("Warning: auto-closed EntityListIterator because of exception: " + e.toString(), module); - } - throw new GeneralRuntimeException(e.getNonNestedMessage(), e.getNested()); - } - } - - /** Moves the cursor to the previous position and returns the GenericValue object for that position; if there is no previous, returns null */ - public GenericValue previous() { - try { - if (resultSet.previous()) { - return currentGenericValue(); - } else { - return null; - } - } catch (SQLException e) { - if (!closed) { - try { - this.close(); - } catch (GenericEntityException e1) { - Debug.logError(e1, "Error auto-closing EntityListIterator on error, so info below for more info on original error; close error: " + e1.toString(), module); - } - Debug.logWarning("Warning: auto-closed EntityListIterator because of exception: " + e.toString(), module); - } - throw new GeneralRuntimeException("Error getting the previous result", e); - } catch (GenericEntityException e) { - if (!closed) { - try { - this.close(); - } catch (GenericEntityException e1) { - Debug.logError(e1, "Error auto-closing EntityListIterator on error, so info below for more info on original error; close error: " + e1.toString(), module); - } - Debug.logWarning("Warning: auto-closed EntityListIterator because of exception: " + e.toString(), module); - } - throw new GeneralRuntimeException("Error creating GenericValue", e); - } - } - - /** Returns the index of the previous result, but does not guarantee that there will be a previous result */ - public int previousIndex() { - try { - return currentIndex() - 1; - } catch (GenericEntityException e) { - if (!closed) { - try { - this.close(); - } catch (GenericEntityException e1) { - Debug.logError(e1, "Error auto-closing EntityListIterator on error, so info below for more info on original error; close error: " + e1.toString(), module); - } - Debug.logWarning("Warning: auto-closed EntityListIterator because of exception: " + e.toString(), module); - } - throw new GeneralRuntimeException("Error getting the current index", e); - } - } - - public void setFetchSize(int rows) throws GenericEntityException { - try { - resultSet.setFetchSize(rows); - } catch (SQLException e) { - if (!closed) { - this.close(); - Debug.logWarning("Warning: auto-closed EntityListIterator because of exception: " + e.toString(), module); - } - throw new GenericEntityException("Error getting the next result", e); - } - } - - public List<GenericValue> getCompleteList() throws GenericEntityException { - try { - // if the resultSet has been moved forward at all, move back to the beginning - if (haveMadeValue && !resultSet.isBeforeFirst()) { - // do a quick check to see if the ResultSet is empty - resultSet.beforeFirst(); - } - List<GenericValue> list = FastList.newInstance(); - GenericValue nextValue = null; - - while ((nextValue = this.next()) != null) { - list.add(nextValue); - } - return list; - } catch (SQLException e) { - if (!closed) { - this.close(); - Debug.logWarning("Warning: auto-closed EntityListIterator because of exception: " + e.toString(), module); - } - throw new GeneralRuntimeException("Error getting results", e); - } catch (GeneralRuntimeException e) { - if (!closed) { - this.close(); - Debug.logWarning("Warning: auto-closed EntityListIterator because of exception: " + e.toString(), module); - } - throw new GenericEntityException(e.getNonNestedMessage(), e.getNested()); - } - } + public void setFetchSize(int rows) throws GenericEntityException; + + public List<GenericValue> getCompleteList() throws GenericEntityException; /** Gets a partial list of results starting at start and containing at most number elements. * Start is a one based value, ie 1 is the first element. */ - public List<GenericValue> getPartialList(int start, int number) throws GenericEntityException { - try { - if (number == 0) return FastList.newInstance(); - List<GenericValue> list = FastList.newInstance(); - - // just in case the caller missed the 1 based thingy - if (start == 0) start = 1; - - // if starting on result 1 just call next() to avoid scrollable issues in some databases - if (start == 1) { - if (!resultSet.next()) { - return list; - } - } else { - // if can't reposition to desired index, throw exception - if (!resultSet.absolute(start)) { - // maybe better to just return an empty list here... - return list; - //throw new GenericEntityException("Could not move to the start position of " + start + ", there are probably not that many results for this find."); - } - } - - // get the first as the current one - list.add(this.currentGenericValue()); - - GenericValue nextValue = null; - // init numRetreived to one since we have already grabbed the initial one - int numRetreived = 1; - - //number > numRetreived comparison goes first to avoid the unwanted call to next - while (number > numRetreived && (nextValue = this.next()) != null) { - list.add(nextValue); - numRetreived++; - } - return list; - } catch (SQLException e) { - if (!closed) { - this.close(); - Debug.logWarning("Warning: auto-closed EntityListIterator because of exception: " + e.toString(), module); - } - throw new GeneralRuntimeException("Error getting results", e); - } catch (GeneralRuntimeException e) { - if (!closed) { - this.close(); - Debug.logWarning("Warning: auto-closed EntityListIterator because of exception: " + e.toString(), module); - } - throw new GenericEntityException(e.getNonNestedMessage(), e.getNested()); - } - } - - public int getResultsSizeAfterPartialList() throws GenericEntityException { - if (this.last()) { - return this.currentIndex(); - } else { - // evidently no valid rows in the ResultSet, so return 0 - return 0; - } - } - - public void add(GenericValue obj) { - throw new GeneralRuntimeException("CursorListIterator currently only supports read-only access"); - } - - public void remove() { - throw new GeneralRuntimeException("CursorListIterator currently only supports read-only access"); - } - - public void set(GenericValue obj) { - throw new GeneralRuntimeException("CursorListIterator currently only supports read-only access"); - } - - @Override - protected void finalize() throws Throwable { - try { - if (!closed) { - this.close(); - Debug.logError("\n====================================================================\n EntityListIterator Not Closed for Entity [" + (modelEntity==null ? "" : modelEntity.getEntityName()) + "], caught in Finalize\n ====================================================================\n", module); - } - } catch (Exception e) { - Debug.logError(e, "Error closing the SQLProcessor in finalize EntityListIterator", module); - } - super.finalize(); - } -} + public List<GenericValue> getPartialList(int start, int number) + throws GenericEntityException; + + public int getResultsSizeAfterPartialList() throws GenericEntityException; + +} \ No newline at end of file |
Free forum by Nabble | Edit this page |