(file) Return to CQLChainedIdentifierRep.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / CQL

  1 chuck 1.1.2.7 //%2003////////////////////////////////////////////////////////////////////////
  2 chuck 1.1.2.6 //
  3               // Copyright (c) 2000, 2001, 2002  BMC Software, Hewlett-Packard Development
  4               // Company, L. P., IBM Corp., The Open Group, Tivoli Systems.
  5 chuck 1.1.2.8 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L. P.;
  6 chuck 1.1.2.6 // IBM Corp.; EMC Corporation, The Open Group.
  7               //
  8               // Permission is hereby granted, free of charge, to any person obtaining a copy
  9               // of this software and associated documentation files (the "Software"), to
 10               // deal in the Software without restriction, including without limitation the
 11               // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 12               // sell copies of the Software, and to permit persons to whom the Software is
 13               // furnished to do so, subject to the following conditions:
 14               // 
 15               // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 16               // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 17               // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 18               // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 19               // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 20               // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 21               // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 22               // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 23               //
 24               //==============================================================================
 25               //
 26               // Authors: David Rosckes (rosckes@us.ibm.com)
 27 chuck 1.1.2.6 //          Bert Rivero (hurivero@us.ibm.com)
 28               //          Chuck Carmack (carmack@us.ibm.com)
 29               //          Brian Lucier (lucier@us.ibm.com)
 30               //
 31               // Modified By: 
 32               //
 33               //%/////////////////////////////////////////////////////////////////////////////
 34               
 35 humberto 1.1.2.1 #include "CQLChainedIdentifier.h"
 36                  #include "CQLChainedIdentifierRep.h"
 37 humberto 1.1.2.2 #include <Pegasus/CQL/CQLFactory.h>
 38 chuck    1.1.2.17 #include <Pegasus/CQL/QueryContext.h>
 39 humberto 1.1.2.18 #include "QueryException.h"
 40 chuck    1.1.2.17 
 41 humberto 1.1.2.1  PEGASUS_NAMESPACE_BEGIN
 42                   
 43 humberto 1.1.2.3  CQLChainedIdentifierRep::CQLChainedIdentifierRep(){
 44                   }
 45                   
 46 humberto 1.1.2.1  CQLChainedIdentifierRep::CQLChainedIdentifierRep(String inString)
 47                   {
 48                   	parse(inString);
 49                   }
 50                   
 51 humberto 1.1.2.12 CQLChainedIdentifierRep::CQLChainedIdentifierRep(const CQLIdentifier &id)
 52 humberto 1.1.2.1  {
 53                           _subIdentifiers.append(id);
 54                   }
 55                   
 56 humberto 1.1.2.3  CQLChainedIdentifierRep::CQLChainedIdentifierRep(const CQLChainedIdentifierRep* rep){
 57                   	_subIdentifiers = rep->_subIdentifiers;
 58                   }
 59                   
 60                   CQLChainedIdentifierRep::~CQLChainedIdentifierRep(){
 61                   	
 62 humberto 1.1.2.1  }
 63                   
 64                   const Array<CQLIdentifier>& CQLChainedIdentifierRep::getSubIdentifiers()const
 65                   {
 66                   	return _subIdentifiers;
 67                   }
 68                   
 69 humberto 1.1.2.12 CQLIdentifier CQLChainedIdentifierRep::getLastIdentifier()const{
 70 humberto 1.1.2.1  	if(_subIdentifiers.size() > 0)
 71                   		return _subIdentifiers[_subIdentifiers.size()-1];
 72                   	return CQLIdentifier();
 73                   }
 74                   
 75                   String CQLChainedIdentifierRep::toString()const{
 76                   	String s;
 77                   	for(Uint32 i = 0; i < _subIdentifiers.size(); i++){
 78                   		s.append(_subIdentifiers[i].toString());
 79                   		if(i < _subIdentifiers.size() - 1)
 80                   			s.append(".");
 81                   	}
 82                   	return s;
 83                   }
 84                   
 85 humberto 1.1.2.12 void CQLChainedIdentifierRep::append(const CQLIdentifier & id){
 86 humberto 1.1.2.1  	_subIdentifiers.append(id);
 87                   }
 88                   
 89 humberto 1.1.2.12 Boolean CQLChainedIdentifierRep::isSubChain(const CQLChainedIdentifier & chain)const{
 90 humberto 1.1.2.1  	Array<CQLIdentifier> ids = chain.getSubIdentifiers();
 91                   	for(Uint32 i = 0; i < ids.size(); i++){
 92                   		if(ids[i] != _subIdentifiers[i].getName())
 93                   			return false;
 94                   	}
 95                   	return true;
 96                   }
 97                   
 98 david    1.1.2.15 CQLIdentifier CQLChainedIdentifierRep::operator[](Uint32 index)const
 99                   {
100                   	return CQLIdentifier(_subIdentifiers[index]);
101 humberto 1.1.2.1  }
102                   
103 humberto 1.1.2.3  CQLChainedIdentifierRep& CQLChainedIdentifierRep::operator=(const CQLChainedIdentifierRep& rhs){
104                   	if(&rhs != this){
105                   		_subIdentifiers = rhs._subIdentifiers;
106                   	}
107                   	return *this;
108                   }
109                   
110 humberto 1.1.2.12 Uint32 CQLChainedIdentifierRep::size()const{
111 humberto 1.1.2.1  	return _subIdentifiers.size();
112                   }
113                   
114 humberto 1.1.2.12 Boolean CQLChainedIdentifierRep::prepend(const CQLIdentifier & id){
115 humberto 1.1.2.1  	/*
116                   	   Compare id against the first element in _subIdentifiers, 
117                   	   if not an exact match, then prepend.  This is used to fully
118                   	   qualify the chained identifier.
119                   	*/
120                   	if(id != _subIdentifiers[0]){
121                   		_subIdentifiers.prepend(id);
122                   		return true;
123                   	}
124                   	return false;
125                   }
126                   
127 chuck    1.1.2.4  void CQLChainedIdentifierRep::applyContext(QueryContext& inContext)
128                   {
129 chuck    1.1.2.9    if (_subIdentifiers.size() == 0)
130                       return;
131                   
132 chuck    1.1.2.11   // Chained identifiers that are standalone symbolic constants 
133                     // should have had the context applied already.  If this method
134                     // is called and this is still a standalone symbolic constant,
135                     // then that is an error.
136                     if (_subIdentifiers.size() == 1 &&
137                         _subIdentifiers[0].getName().getString().size() == 0 &&
138                         _subIdentifiers[0].isSymbolicConstant())
139                     {
140 humberto 1.1.2.18     throw CQLValidationException(
141                                                           MessageLoaderParms(String("CQL.CQLChainedIdentifier.STAND_ALONE_SYMBOLIC_CONSTANT"),
142                                                                              String("The stand alone chained identifier should have had the context applied already."))
143                                                            );
144 chuck    1.1.2.11   }
145                   
146 chuck    1.1.2.5    CQLIdentifier firstId = _subIdentifiers[0];
147                     
148 chuck    1.1.2.13   // Process if the first identifier has some contents.
149                     if ((firstId.getName().getString().size() != 0) || firstId.isWildcard()) 
150 chuck    1.1.2.5    {
151                       Array<CQLIdentifier> fromList = inContext.getFromList();
152                   
153                       if (firstId.isWildcard())
154                       {
155 chuck    1.1.2.16       // First chain element is wildcarded.
156 chuck    1.1.2.13       // Prepend the FROM class.
157 chuck    1.1.2.5        _subIdentifiers.prepend(fromList[0]);
158                       }  
159                       else
160                       {
161 chuck    1.1.2.16       // Not a wildcard.
162 chuck    1.1.2.10       if (firstId.isScoped())
163 chuck    1.1.2.5        {
164 chuck    1.1.2.13         // The first identifier is a scoped property or a 
165                           // scoped symbolic constant.
166                           // Prepend the FROM class.
167                           // Example: SELECT * FROM F WHERE someprop = X::p#'OK'
168 chuck    1.1.2.5  	_subIdentifiers.prepend(fromList[0]);
169                         }
170                         else
171 chuck    1.1.2.10       {
172 chuck    1.1.2.13         // The first identifier is not a scoped property or a scoped
173                           // symbolic constant.
174                   
175                           // Determine if the first identifier's name is in the FROM list.
176 chuck    1.1.2.10 	String classContext = firstId.getName().getString();
177                   	CQLIdentifier matchedId = inContext.findClass(classContext);
178 chuck    1.1.2.14 	if (matchedId.getName().getString().size() == 0)
179 chuck    1.1.2.5  	{
180 chuck    1.1.2.10 	  // Could not find the firstId in the FROM list.
181 chuck    1.1.2.16 	  // Assume the firstId is a property on the FROM class.
182                             // Prepend the FROM class, except in the cases described below.
183 chuck    1.1.2.13           //
184                             // NOTE:
185                             // We need special handling for symbolic constants, because there are cases
186                             // where the first id is a class that is not the FROM class.
187                             // Refer to section 5.4.3 of the CQL spec.
188                             //
189                             // Examples:
190 chuck    1.1.2.16           // SELECT * FROM F WHERE F.someprop = prop#'OK'
191                             // Prepend the FROM class because symbolic constants can only
192                             // apply to properties, and properties in the first position
193                             // are assumed to be on the FROM class.
194                             //
195 chuck    1.1.2.13           // SELECT * FROM F WHERE F.someprop = ClassNotInFromList.prop#'OK'
196                             // We don't want to prepend the FROM class to ClassNotInFromList 
197 chuck    1.1.2.16           // in this case. But we need to get the FROM class from the schema
198                             // to make sure ClassNotInFromList is not a property on the FROM class. 
199 chuck    1.1.2.13           //
200 chuck    1.1.2.16           // SELECT * FROM F WHERE F.someprop = embeddedObjectOnF.X::p#'OK'
201                             // In this case embeddedObjectOnF is an embedded object property
202                             // on the FROM class.  We want to prepend the FROM class.  But
203                             // we need to get FROM class from the schema first to make sure.
204                             //
205                             // SELECT * FROM F WHERE F.someprop = embeddedObjectOnF.X::p
206                             // In this case embeddedObjectOnF is an embedded object property
207                             // on the FROM class.  We want to prepend the FROM class.  Since
208                             // the last id is not a symbolic constant we can prepend without
209                             // getting the FROM class from the schema.
210 chuck    1.1.2.13           //
211                             // Note that standalone symbolic constants, like #'OK'
212 chuck    1.1.2.16           // are errors when this code is run.
213 chuck    1.1.2.13           // See above for details.
214                             //
215 chuck    1.1.2.16 
216                             if (firstId.isSymbolicConstant() ||
217                                 !getLastIdentifier().isSymbolicConstant()) 
218                             {
219                               // Must be a property on the FROM class.
220                   	    _subIdentifiers.prepend(fromList[0]);            
221                             }
222                             else
223                             {
224                               // Get the FROM class. 
225                               try
226                               {
227                                 CIMClass fromClass = inContext.getClass(fromList[0].getName());
228                                 if (fromClass.findProperty(firstId.getName()) != PEG_NOT_FOUND)
229                                 {
230                                   // A property on the FROM class.
231                                   _subIdentifiers.prepend(fromList[0]);                              
232                                 }
233                               }
234                               catch (CIMException& ce)
235                               {
236 chuck    1.1.2.16               if (ce.getCode() == CIM_ERR_INVALID_CLASS || 
237                                     ce.getCode() == CIM_ERR_NOT_FOUND)
238                                 {
239                                   // ATTN may just want to throw the CIMException rather than
240                                   // CQL exception
241                                   throw Exception("TEMP MSG - CQLChainId::applyContext - FROM class does not exist");
242 humberto 1.1.2.18 		throw CQLValidationException(
243                                                           MessageLoaderParms(String("CQL.CQLChainedIdentifier.FROM_CLASS_DOES_NOT_EXIST"),
244                                                                              String("The FROM class does not exist while applying context."))
245                                                            );
246 chuck    1.1.2.16               }
247                               }
248                             }
249 chuck    1.1.2.10 	}
250                   	else
251                   	{	
252                   	  // The firstId was found in the FROM list, but it could have been 
253                   	  // an alias
254                   	  if (!matchedId.getName().equal(firstId.getName()))
255                   	  {
256                   	    // It was an alias.
257                   	    // Replace the alias with the FROM class
258                   	    _subIdentifiers[0] = matchedId;
259                   	  }
260                   	  else 
261                   	  {
262                   	    // It was not an alias. Do nothing.
263                   	    ;
264                   	  }
265 chuck    1.1.2.5  	}
266                         }
267                       }
268                     }
269 chuck    1.1.2.10   
270 chuck    1.1.2.13   // Go through and replace any aliases on scoping classes
271 chuck    1.1.2.10   for (Uint32 i = 0; i < _subIdentifiers.size(); i++)
272                     {
273                       if (_subIdentifiers[i].isScoped())
274                       {
275                         CQLIdentifier match = inContext.findClass(_subIdentifiers[i].getScope());
276 chuck    1.1.2.13       if (match.getName().getString().size() != 0)
277 chuck    1.1.2.10       {
278 chuck    1.1.2.13         // The scoping class was either the FROM class, or an alias of the
279                           // FROM class.  Replace the scoping class with the FROM class.
280 chuck    1.1.2.10 	_subIdentifiers[i].applyScope(match.getName().getString());
281                         }
282                       }
283                     }
284 humberto 1.1.2.1  }
285                   
286                   void CQLChainedIdentifierRep::parse(String & string){
287                   	/* 
288                   	  - parse string on "."
289                   	  - start from the end of string
290                   	  - if more than one substring found, 
291                   		-- store first found string then
292                   		-- prepend remaining substrings 
293                   	*/
294                   	Char16 delim('.');
295                   	Uint32 index;
296                   	String range;
297                   
298                   	/* remove any array ranges so we dont parse a false . */
299                   	if((index = string.find("[")) != PEG_NOT_FOUND){
300                   		range = string.subString(index);
301                   		string.remove(index);
302                   	}
303                   
304                   	index = string.reverseFind(delim);
305 humberto 1.1.2.1  	if(index == PEG_NOT_FOUND){
306                   		/* append the range we may have removed */
307                   		string.append(range);
308                   		_subIdentifiers.append(CQLIdentifier(string));
309                   	}else{
310                   		/* append the range we may have removed */
311                   		String tmp = string.subString(index+1);
312                   		tmp.append(range);
313                   		_subIdentifiers.append(CQLIdentifier(tmp));
314                   
315                   		while(index != PEG_NOT_FOUND){
316                   			tmp = string.subString(0,index);
317                   			index = tmp.reverseFind(delim);
318                   			if(index == PEG_NOT_FOUND){
319                   				_subIdentifiers.prepend(CQLIdentifier(tmp));
320                   			}
321                   			else{
322                   				_subIdentifiers.prepend(CQLIdentifier(tmp.subString(index+1)));
323                   			}
324                   		}
325                   	}
326 humberto 1.1.2.1  }
327                   
328                   PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2