| /* |
| * 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.apache.openjpa.meta; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.apache.openjpa.kernel.QueryLanguages; |
| |
| |
| |
| /** |
| * Extends {@link QueryMetaData} to allow multiple {@link QueryMetaData#getResultType() result class} or |
| * {@link QueryMetaData#getResultSetMappingName() mapping names}. |
| * <br> |
| * Designed for mapping the results from a Stored Procudure that can produce more than one {@link java.sql.ResultSet}, |
| * each being mapped with a different mapping specification. |
| * |
| * |
| * @author Pinaki Poddar |
| * |
| */ |
| public class MultiQueryMetaData extends QueryMetaData { |
| private static final long serialVersionUID = 1L; |
| private final String _procedureName; |
| private final boolean _isTemporary; |
| private final List<QueryMetaData> _parts = new ArrayList<>(); |
| private final List<Parameter> _params = new ArrayList<>(); |
| |
| /** |
| * Create this meta data given a scope of definition, a logical identifier, a procedure name |
| * and whether its usage is temporary. |
| * @param scope defining scope |
| * @param logicalName name as an identifier |
| * @param procedureName name of the database procedure |
| */ |
| public MultiQueryMetaData(Class<?> scope, String logicalName, String procedureName, boolean isTemporary) { |
| super(logicalName, false); |
| setLanguage(QueryLanguages.LANG_STORED_PROC); |
| setSource(null, scope, -1, null); |
| _procedureName = procedureName; |
| _isTemporary = isTemporary; |
| } |
| |
| public String getProcedureName() { |
| return _procedureName; |
| } |
| |
| public List<QueryMetaData> getComponents() { |
| return _parts; |
| } |
| |
| /** |
| * Affirms if this metadata is ephimeral. |
| * Ephimenral metadata is removed from the repository after usage. |
| * @return |
| */ |
| public boolean isEphimeral() { |
| return _isTemporary; |
| } |
| |
| @Override |
| public void setResultSetMappingName(String name) { |
| throw new UnsupportedOperationException("Not allowed to set mapping name. It is automatically set"); |
| } |
| |
| @Override |
| public void setResultType(Class cls) { |
| throw new UnsupportedOperationException("Not allowed to set result type. It is automatically set"); |
| } |
| |
| public void addComponent(Class<?> resultClass) { |
| QueryMetaData part = newQueryMetaData(); |
| part.setResultType(resultClass); |
| _parts.add(part); |
| } |
| |
| public void addComponent(String mappingName) { |
| QueryMetaData part = newQueryMetaData(); |
| part.setResultSetMappingName(mappingName); |
| _parts.add(part); |
| } |
| |
| private QueryMetaData newQueryMetaData() { |
| QueryMetaData part = new QueryMetaData(getName() + "#" + _parts.size(), false); |
| part.setLanguage(getLanguage()); |
| part.setSource(null, getDefiningType(), -1, null); |
| return part; |
| } |
| |
| |
| /** |
| * Gets the component metadata at the given part index. |
| * @param i a valid integer index |
| * @return |
| */ |
| public QueryMetaData getComponent(int i) { |
| if (i < 0 || i >= _parts.size()) { |
| throw new ArrayIndexOutOfBoundsException("Invalid index " + i |
| + ". Available " + _parts.size() + " parts"); |
| } |
| return _parts.get(i); |
| } |
| |
| /** |
| * Gets the number of component metadata contained in this metada. |
| */ |
| public int getComponentCount() { |
| return _parts.size(); |
| } |
| |
| /** |
| * Registers the given parameter. |
| * @param p |
| */ |
| public void registerParameter(Parameter p) { |
| _params.add(p); |
| } |
| |
| public List<Parameter> getParameters() { |
| return _params; |
| } |
| |
| public int getParameterCount() { |
| return _params.size(); |
| } |
| |
| |
| /** |
| * A parameter |
| * |
| */ |
| public static class Parameter { |
| public enum Mode {IN,OUT,INOUT,CURSOR} |
| |
| private final String name; |
| private final Class<?> type; |
| private final Mode mode; |
| private final int position; |
| |
| public Parameter(String name, Class<?> type, Mode mode) { |
| this.name = name; |
| this.type = type; |
| this.mode = mode; |
| this.position = -1; |
| } |
| |
| public Parameter(int position, Class<?> type, Mode mode) { |
| this.name = null; |
| this.type = type; |
| this.mode = mode; |
| this.position = position; |
| } |
| |
| public int getPosition() { |
| return position; |
| } |
| |
| public String getName() { |
| return name; |
| } |
| |
| public Class<?> getType() { |
| return type; |
| } |
| |
| public Mode getMode() { |
| return mode; |
| } |
| } |
| |
| |
| |
| } |