xml.xpath.ext/src/org/netbeans/modules/xml/xpath/ext/XPathUtils.java
author Milutin Kristofic <mkristofic@netbeans.org>
Mon, 30 Jan 2017 14:30:54 +0100
changeset 1583 fe20f672a61a
parent 1305 619e3fca5c2f
permissions -rw-r--r--
Added Missing copyright information in source files
mkristofic@1583
     1
/*
mkristofic@1583
     2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
mkristofic@1583
     3
 *
mkristofic@1583
     4
 * Copyright 2009-2017 Oracle and/or its affiliates. All rights reserved.
mkristofic@1583
     5
 *
mkristofic@1583
     6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
mkristofic@1583
     7
 * Other names may be trademarks of their respective owners.
mkristofic@1583
     8
 *
mkristofic@1583
     9
 * The contents of this file are subject to the terms of either the GNU
mkristofic@1583
    10
 * General Public License Version 2 only ("GPL") or the Common
mkristofic@1583
    11
 * Development and Distribution License("CDDL") (collectively, the
mkristofic@1583
    12
 * "License"). You may not use this file except in compliance with the
mkristofic@1583
    13
 * License. You can obtain a copy of the License at
mkristofic@1583
    14
 * http://www.netbeans.org/cddl-gplv2.html
mkristofic@1583
    15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
mkristofic@1583
    16
 * specific language governing permissions and limitations under the
mkristofic@1583
    17
 * License.  When distributing the software, include this License Header
mkristofic@1583
    18
 * Notice in each file and include the License file at
mkristofic@1583
    19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
mkristofic@1583
    20
 * particular file as subject to the "Classpath" exception as provided
mkristofic@1583
    21
 * by Oracle in the GPL Version 2 section of the License file that
mkristofic@1583
    22
 * accompanied this code. If applicable, add the following below the
mkristofic@1583
    23
 * License Header, with the fields enclosed by brackets [] replaced by
mkristofic@1583
    24
 * your own identifying information:
mkristofic@1583
    25
 * "Portions Copyrighted [year] [name of copyright owner]"
mkristofic@1583
    26
 *
mkristofic@1583
    27
 * Contributor(s):
mkristofic@1583
    28
 *
mkristofic@1583
    29
 * The Original Software is NetBeans. The Initial Developer of the Original
mkristofic@1583
    30
 * Software is Sun Microsystems, Inc. Portions Copyright 2009-2010 Sun
mkristofic@1583
    31
 * Microsystems, Inc. All Rights Reserved.
mkristofic@1583
    32
 *
mkristofic@1583
    33
 * If you wish your version of this file to be governed by only the CDDL
mkristofic@1583
    34
 * or only the GPL Version 2, indicate your decision by adding
mkristofic@1583
    35
 * "[Contributor] elects to include this software in this distribution
mkristofic@1583
    36
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
mkristofic@1583
    37
 * single choice of license, a recipient has the option to distribute
mkristofic@1583
    38
 * your version of this file under either the CDDL, the GPL Version 2 or
mkristofic@1583
    39
 * to extend the choice of license to its licensees as provided above.
mkristofic@1583
    40
 * However, if you add GPL Version 2 code and therefore, elected the GPL
mkristofic@1583
    41
 * Version 2 license, then the option applies only if the new code is
mkristofic@1583
    42
 * made subject to such option by the copyright holder.
mkristofic@1583
    43
 */
yaroslavskiy@641
    44
/*
yaroslavskiy@641
    45
 * Utils.java
yaroslavskiy@641
    46
 * 
yaroslavskiy@641
    47
 * Created on 31.08.2007, 15:40:45
yaroslavskiy@641
    48
 * 
yaroslavskiy@641
    49
 * To change this template, choose Tools | Templates
yaroslavskiy@641
    50
 * and open the template in the editor.
yaroslavskiy@641
    51
 */
yaroslavskiy@641
    52
yaroslavskiy@641
    53
package org.netbeans.modules.xml.xpath.ext;
yaroslavskiy@641
    54
supernikita@949
    55
import java.util.ArrayList;
supernikita@949
    56
import java.util.Collection;
supernikita@804
    57
import java.util.List;
supernikita@949
    58
import java.util.Set;
supernikita@746
    59
import javax.xml.namespace.NamespaceContext;
yaroslavskiy@641
    60
import javax.xml.namespace.QName;
alexpetrov@718
    61
import org.netbeans.modules.xml.schema.model.ElementReference;
alexpetrov@718
    62
import org.netbeans.modules.xml.schema.model.Form;
alexpetrov@718
    63
import org.netbeans.modules.xml.schema.model.GlobalAttribute;
alexpetrov@718
    64
import org.netbeans.modules.xml.schema.model.GlobalElement;
alexpetrov@718
    65
import org.netbeans.modules.xml.schema.model.LocalAttribute;
alexpetrov@718
    66
import org.netbeans.modules.xml.schema.model.LocalElement;
supernikita@949
    67
import org.netbeans.modules.xml.schema.model.Schema;
alexpetrov@718
    68
import org.netbeans.modules.xml.schema.model.SchemaComponent;
supernikita@949
    69
import org.netbeans.modules.xml.schema.model.SchemaModel;
supernikita@804
    70
import org.netbeans.modules.xml.xpath.ext.schema.FindAllChildrenSchemaVisitor;
supernikita@949
    71
import org.netbeans.modules.xml.xpath.ext.schema.FindChildrenSchemaVisitor;
supernikita@949
    72
import org.netbeans.modules.xml.xpath.ext.schema.resolver.SchemaCompHolder;
supernikita@1305
    73
import org.netbeans.modules.xml.xpath.ext.schema.resolver.WrappingSchemaContext;
supernikita@949
    74
import org.netbeans.modules.xml.xpath.ext.schema.resolver.XPathSchemaContext;
supernikita@949
    75
import org.netbeans.modules.xml.xpath.ext.schema.resolver.XPathSchemaContext.SchemaCompPair;
supernikita@949
    76
import org.netbeans.modules.xml.xpath.ext.spi.ExternalModelResolver;
supernikita@949
    77
import org.netbeans.modules.xml.xpath.ext.spi.XPathCastResolver;
supernikita@949
    78
import org.netbeans.modules.xml.xpath.ext.spi.XPathPseudoComp;
supernikita@1305
    79
import org.netbeans.modules.xml.xpath.ext.visitor.ExpressionComparatorVisitor;
yaroslavskiy@641
    80
yaroslavskiy@641
    81
/**
yaroslavskiy@641
    82
 * Utility class.
yaroslavskiy@641
    83
 * 
yaroslavskiy@641
    84
 * @author nk160297
yaroslavskiy@641
    85
 */
yaroslavskiy@641
    86
public class XPathUtils {
yaroslavskiy@641
    87
supernikita@1305
    88
    public static boolean equal(Object o1, Object o2) {
supernikita@1305
    89
        if (o1 == o2) return true;
supernikita@1305
    90
        return (o1 == null || o2 == null) ? false : o1.equals(o2);
supernikita@1305
    91
    }
supernikita@1305
    92
yaroslavskiy@641
    93
    /**
yaroslavskiy@641
    94
     * Converts the qName to a String. 
yaroslavskiy@641
    95
     * Only the prefix and the local part is used. 
yaroslavskiy@641
    96
     * The namespace URI is ignored. 
yaroslavskiy@641
    97
     * 
yaroslavskiy@641
    98
     * This method is intended to print an entity.
yaroslavskiy@641
    99
     */ 
yaroslavskiy@641
   100
    public static String qNameObjectToString(QName qName) {
yaroslavskiy@641
   101
        String prefix = qName.getPrefix();
yaroslavskiy@641
   102
        if (prefix == null || prefix.length() == 0) {
yaroslavskiy@641
   103
            return qName.getLocalPart();
yaroslavskiy@641
   104
        } else {
yaroslavskiy@641
   105
            return prefix + ":" + qName.getLocalPart();
yaroslavskiy@641
   106
        }
yaroslavskiy@641
   107
                
yaroslavskiy@641
   108
    }
yaroslavskiy@641
   109
    
yaroslavskiy@641
   110
    /**
yaroslavskiy@641
   111
     * Converts the qName to a String. 
yaroslavskiy@641
   112
     * Only the prefix and the namespace URI is used. 
yaroslavskiy@641
   113
     * The local part is ignored. 
yaroslavskiy@641
   114
     * 
yaroslavskiy@641
   115
     * This method is intended to print a namespace which is held in a QName.
yaroslavskiy@641
   116
     */ 
yaroslavskiy@641
   117
    public static String gNameNamespaceToString(QName qName) {
yaroslavskiy@641
   118
        String prefix = qName.getPrefix();
yaroslavskiy@641
   119
        String nsUri = qName.getNamespaceURI();
yaroslavskiy@641
   120
        //
yaroslavskiy@641
   121
        if (prefix == null || prefix.length() == 0) {
yaroslavskiy@641
   122
            return "{" + nsUri + "}";
yaroslavskiy@641
   123
        } else {
yaroslavskiy@641
   124
            return "{" + nsUri + "}" + prefix;
yaroslavskiy@641
   125
        }
yaroslavskiy@641
   126
    }
yaroslavskiy@641
   127
    
supernikita@746
   128
    /**
supernikita@746
   129
     * Check if the namespace URI is specified for the name. 
supernikita@746
   130
     * If the name isn't specified, then try resolve it from the prefix.
supernikita@746
   131
     * Returns the corrected name if possible. Otherwise returns old name.
supernikita@746
   132
     * @param nsContext
supernikita@746
   133
     * @param name
supernikita@746
   134
     * @return
supernikita@746
   135
     */
supernikita@746
   136
    public static QName resolvePrefix(NamespaceContext nsContext, QName name) {
supernikita@746
   137
        String nsUri = name.getNamespaceURI();
supernikita@746
   138
        if (nsUri == null || nsUri.length() == 0 && nsContext != null) {
supernikita@746
   139
            //
supernikita@746
   140
            String nsPrefix = name.getPrefix();
supernikita@746
   141
            nsUri = nsContext.getNamespaceURI(nsPrefix);
supernikita@746
   142
            //
supernikita@746
   143
            if (nsUri != null) {
supernikita@746
   144
                String localPart = name.getLocalPart();
supernikita@746
   145
                QName newName = new QName(nsUri, localPart);
supernikita@746
   146
                name = newName;
supernikita@746
   147
            }
supernikita@746
   148
        }
supernikita@746
   149
        //
supernikita@746
   150
        return name;
supernikita@746
   151
    }
supernikita@746
   152
    
supernikita@712
   153
    public static boolean equalsIgnorNsUri(QName qName1, QName qName2) {
supernikita@712
   154
        return (qName1.getLocalPart().equals(qName2.getLocalPart())) && 
supernikita@712
   155
                (qName1.getPrefix().equals(qName2.getPrefix()));
supernikita@712
   156
    }
supernikita@712
   157
    
supernikita@712
   158
    public static boolean samePredicatesArr(
supernikita@712
   159
            XPathPredicateExpression[] predArr1, 
supernikita@712
   160
            XPathPredicateExpression[] predArr2) {
supernikita@712
   161
        //
supernikita@1305
   162
        if (predArr1 == predArr2) {
supernikita@1305
   163
            return true;
supernikita@1305
   164
        }
supernikita@1305
   165
        if (predArr1 == null || predArr2 == null) {
supernikita@1305
   166
            return false;
supernikita@1305
   167
        }
supernikita@1305
   168
        //
supernikita@712
   169
        // Compare predicates count
supernikita@1305
   170
        int size1 = predArr1 == null ? 0 : predArr1.length;
supernikita@1305
   171
        int size2 = predArr2 == null ? 0 : predArr2.length;
supernikita@1305
   172
        if (size1 != size2) {
supernikita@712
   173
            return false;
supernikita@712
   174
        }
supernikita@712
   175
        // Compare predicates one by one
supernikita@1305
   176
        //
supernikita@1305
   177
        // It is implied that the order is the same. 
supernikita@1305
   178
        // So the same sets of predicates but with different order 
supernikita@1305
   179
        // are considered different. 
supernikita@1305
   180
        for (int index = 0; index < size1; index++) {
supernikita@712
   181
            XPathPredicateExpression predicate1 = predArr1[index];
supernikita@712
   182
            XPathPredicateExpression predicate2 = predArr2[index];
supernikita@1305
   183
            //
supernikita@1305
   184
            XPathExpression predExpr1 = predicate1.getPredicate();
supernikita@1305
   185
            XPathExpression predExpr2 = predicate2.getPredicate();
supernikita@1305
   186
            //
supernikita@1305
   187
            if (predExpr1 instanceof XPathSchemaContextHolder &&
supernikita@1305
   188
                    predExpr2 instanceof XPathSchemaContextHolder) {
supernikita@1305
   189
                // If both predicate expressions are schema context holders,
supernikita@1305
   190
                // then compare contexts.
supernikita@1305
   191
                //
supernikita@1305
   192
                XPathSchemaContext ctxt1 =
supernikita@1305
   193
                        ((XPathSchemaContextHolder)predExpr1).getSchemaContext();
supernikita@1305
   194
                XPathSchemaContext ctxt2 =
supernikita@1305
   195
                        ((XPathSchemaContextHolder)predExpr2).getSchemaContext();
supernikita@1305
   196
                //
supernikita@1305
   197
                if (!equal(ctxt1, ctxt2)) {
supernikita@1305
   198
                    return false;
supernikita@1305
   199
                }
supernikita@1305
   200
            } else {
supernikita@1305
   201
                if (!ExpressionComparatorVisitor.equals(predExpr1, predExpr2)) {
supernikita@1305
   202
                    return false;
supernikita@1305
   203
                }
supernikita@712
   204
            }
supernikita@712
   205
        }
supernikita@712
   206
        return true;
supernikita@712
   207
    }
supernikita@712
   208
    
alexpetrov@718
   209
    /**
alexpetrov@718
   210
     * Determines if a namespace prefix is required for the specified schema component. 
alexpetrov@718
   211
     * @param sComp
alexpetrov@718
   212
     * @return
alexpetrov@718
   213
     */
alexpetrov@718
   214
    public static boolean isPrefixRequired(SchemaComponent sComp) {
alexpetrov@718
   215
        if (sComp instanceof LocalElement) {
alexpetrov@718
   216
            Form form = ((LocalElement)sComp).getFormEffective();
alexpetrov@718
   217
            if (form == Form.QUALIFIED) {
alexpetrov@718
   218
                return true;
alexpetrov@718
   219
            } else {
alexpetrov@718
   220
                return false;
alexpetrov@718
   221
            }
alexpetrov@718
   222
        } else if (sComp instanceof GlobalElement) {
alexpetrov@718
   223
            return true;
alexpetrov@718
   224
        } else if (sComp instanceof LocalAttribute) {
alexpetrov@718
   225
            Form form = ((LocalAttribute)sComp).getFormEffective();
alexpetrov@718
   226
            if (form == Form.QUALIFIED) {
alexpetrov@718
   227
                return true;
alexpetrov@718
   228
            } else {
alexpetrov@718
   229
                return false;
alexpetrov@718
   230
            }
alexpetrov@718
   231
        } else if (sComp instanceof GlobalElement || 
alexpetrov@718
   232
                sComp instanceof ElementReference || 
alexpetrov@718
   233
                sComp instanceof GlobalAttribute) {
alexpetrov@718
   234
            // all global objects have to be with a prefix
alexpetrov@718
   235
            return true;
alexpetrov@718
   236
        }
alexpetrov@718
   237
        //
alexpetrov@718
   238
        assert true : "Unsupported schema component in the BPEL mapper tree!"; // NOI18N
alexpetrov@718
   239
        return false;
alexpetrov@718
   240
    }
supernikita@804
   241
    
supernikita@804
   242
    /**
supernikita@804
   243
     * Checks if the specified Schema component has any subcomponents.
supernikita@804
   244
     * @param sComp
supernikita@804
   245
     * @return
supernikita@804
   246
     */
supernikita@804
   247
    public static boolean hasSubcomponents(SchemaComponent sComp) {
supernikita@804
   248
        FindAllChildrenSchemaVisitor checker = 
supernikita@925
   249
                new FindAllChildrenSchemaVisitor(true, true, true);
supernikita@804
   250
        checker.lookForSubcomponents(sComp);
supernikita@804
   251
        List<SchemaComponent> found = checker.getFound();
supernikita@804
   252
        return found != null && !found.isEmpty();
supernikita@804
   253
    }
supernikita@949
   254
    
supernikita@949
   255
    /**
supernikita@949
   256
     * Constructs a list of SchemaCompPair objects. Each SchemaCompPair represents 
supernikita@949
   257
     * a child Schema component of a parent. Parents are taken from the 
supernikita@949
   258
     * specified parent SchemaContext. The context can contain several schema
supernikita@949
   259
     * components. So children mean children of all possible parent components 
supernikita@949
   260
     * in current context. 
supernikita@949
   261
     * 
supernikita@949
   262
     * Childrent can be real children schema components or pseudo components. 
supernikita@949
   263
     * See XPathPseudoComp class.
supernikita@949
   264
     * 
supernikita@949
   265
     * @param xPathModel
supernikita@949
   266
     * @param parentSContext
supernikita@949
   267
     * @param lookForElements indicates if it necessary to add elements to 
supernikita@949
   268
     * the result list.
supernikita@949
   269
     * @param lookForAttributes indicates if it necessary to add attributes to 
supernikita@949
   270
     * the result list.
supernikita@949
   271
     * @param collectAny indicates if it necessary to add xsd:any or 
supernikita@949
   272
     * xsd:anyAttribute to the result list. 
supernikita@949
   273
     * @return result list
supernikita@949
   274
     */
supernikita@949
   275
    public static List<SchemaCompPair> findSubcomponents(
supernikita@949
   276
            XPathModel xPathModel, XPathSchemaContext parentSContext, 
supernikita@949
   277
            boolean lookForElements, boolean lookForAttributes, boolean collectAny) {
supernikita@949
   278
        //
supernikita@949
   279
        assert parentSContext != null;
supernikita@949
   280
        ArrayList<SchemaCompPair> result = new ArrayList<SchemaCompPair>();
supernikita@949
   281
        //
supernikita@1305
   282
        XPathCastResolver castResolver = xPathModel == null ? null :
supernikita@1305
   283
            xPathModel.getXPathCastResolver();
supernikita@949
   284
        Set<SchemaCompPair> parentCompPairSet = parentSContext.getSchemaCompPairs(); 
supernikita@949
   285
        //
supernikita@949
   286
        boolean processPseudoComp = 
supernikita@949
   287
                castResolver != null && parentCompPairSet.size() == 1;
supernikita@949
   288
        //
supernikita@949
   289
        for (SchemaCompPair parentCompPair : parentCompPairSet) {
supernikita@949
   290
            SchemaCompHolder parentCompHolder = parentCompPair.getCompHolder();
supernikita@949
   291
            //
supernikita@949
   292
            FindAllChildrenSchemaVisitor visitor = 
supernikita@949
   293
                    new FindAllChildrenSchemaVisitor(
supernikita@949
   294
                    lookForElements, lookForAttributes, false);
supernikita@949
   295
            visitor.lookForSubcomponents(parentCompHolder.getSchemaComponent());
supernikita@949
   296
            //
supernikita@949
   297
            List<SchemaComponent> foundComps = visitor.getFound();
supernikita@949
   298
            for (SchemaComponent foundComp : foundComps) {
supernikita@949
   299
                SchemaCompPair newPair = 
supernikita@949
   300
                        new SchemaCompPair(foundComp, parentCompHolder);
supernikita@949
   301
                result.add(newPair);
supernikita@949
   302
            }
supernikita@949
   303
            //
supernikita@949
   304
            if (processPseudoComp) {
supernikita@949
   305
                if (visitor.hasAny() || visitor.hasAnyAttribute()) {
supernikita@949
   306
                    List<XPathPseudoComp> pcList = 
supernikita@949
   307
                            castResolver.getPseudoCompList(parentSContext);
supernikita@949
   308
                    for (XPathPseudoComp pseudoComp : pcList) {
supernikita@949
   309
                        if (pseudoComp.isAttribute()) {
supernikita@949
   310
                            if (lookForAttributes && visitor.hasAnyAttribute()) {
supernikita@949
   311
                                SchemaCompHolder scHolder = 
supernikita@949
   312
                                        SchemaCompHolder.Factory.construct(pseudoComp);
supernikita@949
   313
                                SchemaCompPair newPair = 
supernikita@949
   314
                                        new SchemaCompPair(scHolder, parentCompHolder);
supernikita@949
   315
                                result.add(newPair);
supernikita@949
   316
                            }
supernikita@949
   317
                        } else {
supernikita@949
   318
                            if (lookForElements && visitor.hasAny()) {
supernikita@949
   319
                                SchemaCompHolder scHolder = 
supernikita@949
   320
                                        SchemaCompHolder.Factory.construct(pseudoComp);
supernikita@949
   321
                                SchemaCompPair newPair = 
supernikita@949
   322
                                        new SchemaCompPair(scHolder, parentCompHolder);
supernikita@949
   323
                                result.add(newPair);
supernikita@949
   324
                            }
supernikita@949
   325
                        }
supernikita@949
   326
                    }
supernikita@949
   327
                }
supernikita@949
   328
            }
supernikita@949
   329
        }
supernikita@949
   330
        //
supernikita@949
   331
        return result;
supernikita@949
   332
    }
supernikita@949
   333
    
supernikita@949
   334
    /**
supernikita@949
   335
     * Collects a list of SchemaCompHoder objects, which are global accessible.
supernikita@949
   336
     * 
supernikita@949
   337
     * @param xPathModel
supernikita@949
   338
     * @param lookForElements indicates if it necessary to add elements to 
supernikita@949
   339
     * the result list.
supernikita@949
   340
     * @param lookForAttributes indicates if it necessary to add attributes to 
supernikita@949
   341
     * the result list.
supernikita@949
   342
     * @param collectAny indicates if it necessary to add xsd:any or 
supernikita@949
   343
     * xsd:anyAttribute to the result list. 
supernikita@949
   344
     * @return result list
supernikita@949
   345
     */
supernikita@949
   346
    public static List<SchemaComponent> findRootComponents(XPathModel xPathModel, 
supernikita@949
   347
            boolean lookForElements, boolean lookForAttributes, boolean collectAny) {
supernikita@949
   348
        //
supernikita@949
   349
        ArrayList<SchemaComponent> result = new ArrayList<SchemaComponent>();
supernikita@949
   350
        //
supernikita@949
   351
        ExternalModelResolver exModelResolver = xPathModel.getExternalModelResolver();
supernikita@949
   352
        //
supernikita@949
   353
        if (exModelResolver != null) {
supernikita@949
   354
            //
supernikita@949
   355
            // Look for all available root elements (attributes) 
supernikita@949
   356
            // in all available models
supernikita@949
   357
            // Pseudo components can be only inside of another schema components, 
supernikita@949
   358
            // So they can't be global. It doesn't necessary to look them here.
supernikita@949
   359
            Collection<SchemaModel> sModels = exModelResolver.getVisibleModels();
supernikita@949
   360
            for (SchemaModel sModel : sModels) {
supernikita@949
   361
                Schema schema = sModel.getSchema();
supernikita@1305
   362
                if (schema != null) {
supernikita@1305
   363
                    FindAllChildrenSchemaVisitor visitor =
supernikita@1305
   364
                            new FindAllChildrenSchemaVisitor(
supernikita@1305
   365
                            lookForElements, lookForAttributes, false);
supernikita@1305
   366
                    visitor.lookForSubcomponents(schema);
supernikita@1305
   367
                    //
supernikita@1305
   368
                    List<SchemaComponent> foundComps = visitor.getFound();
supernikita@1305
   369
                    result.addAll(foundComps);
supernikita@1305
   370
                }
supernikita@949
   371
            }
supernikita@949
   372
        }
supernikita@949
   373
        //
supernikita@949
   374
        return result;
supernikita@949
   375
    }
supernikita@949
   376
    
supernikita@949
   377
    /**
supernikita@949
   378
     * Returns the list of SchemaCompHolder components, which are children 
supernikita@949
   379
     * of the specified parent schema component component (and context) 
supernikita@949
   380
     * and have specified name and namespace. 
supernikita@949
   381
     * Usually only one component has to be returned. 
supernikita@949
   382
     * Not only real schema components can be childrent but also pseudo components, 
supernikita@949
   383
     * which are result of casting xsd:any or xsd:anyAttribute. 
supernikita@949
   384
     * 
supernikita@949
   385
     * @param xPathModel
supernikita@949
   386
     * @param parentContext
supernikita@949
   387
     * @param parent 
supernikita@949
   388
     * @param soughtName required name
supernikita@949
   389
     * @param soughtNamespace required namespace
supernikita@949
   390
     * @param isAttribute indicates if an attribute or element is required
supernikita@949
   391
     * It can be null. 
supernikita@949
   392
     * @return
supernikita@949
   393
     */
supernikita@949
   394
    public static List<SchemaCompHolder> getChildren(
supernikita@949
   395
            XPathModel xPathModel, XPathSchemaContext parentContext,
supernikita@949
   396
            SchemaComponent parent, String soughtName, 
supernikita@1264
   397
            String soughtNamespace, boolean isAttribute) {
supernikita@949
   398
        List<SchemaComponent> found = null;
supernikita@949
   399
        boolean hasAny = false;
supernikita@949
   400
        boolean hasAnyAttribute = false;
supernikita@949
   401
        ArrayList<SchemaCompHolder> result = new ArrayList<SchemaCompHolder>();
supernikita@949
   402
        //
supernikita@1264
   403
        FindChildrenSchemaVisitor visitor =
supernikita@1264
   404
                new FindChildrenSchemaVisitor(parentContext,
supernikita@1264
   405
                soughtName, soughtNamespace, isAttribute);
supernikita@1264
   406
        visitor.lookForSubcomponent(parent);
supernikita@1264
   407
        found = visitor.getFound();
supernikita@1264
   408
        hasAny = visitor.hasAny();
supernikita@1264
   409
        hasAnyAttribute = visitor.hasAnyAttribute();
supernikita@949
   410
        //
supernikita@949
   411
        if (found == null || found.isEmpty()) {
supernikita@949
   412
            //
supernikita@949
   413
            // try looking for Pseudo Components here
supernikita@949
   414
            XPathCastResolver castResolver = xPathModel.getXPathCastResolver();
supernikita@949
   415
            if (castResolver != null) {
supernikita@949
   416
                List<XPathPseudoComp> pcList = 
supernikita@949
   417
                        castResolver.getPseudoCompList(parentContext);
supernikita@949
   418
                if (pcList != null) {
supernikita@949
   419
                    for (XPathPseudoComp pseudoComp : pcList) {
supernikita@949
   420
                        if (!hasAnyAttribute && isAttribute) {
supernikita@949
   421
                            // AnyAttribute isn't supported
supernikita@949
   422
                            continue;
supernikita@949
   423
                        }
supernikita@949
   424
                        //
supernikita@949
   425
                        if (!hasAny && !isAttribute) {
supernikita@949
   426
                            // Any isn't supported
supernikita@949
   427
                            continue;
supernikita@949
   428
                        }
supernikita@949
   429
                        //
supernikita@949
   430
                        if (isAttribute != pseudoComp.isAttribute()) {
supernikita@949
   431
                            continue;
supernikita@949
   432
                        }
supernikita@949
   433
                        //
supernikita@949
   434
                        if (!(soughtName.equals(pseudoComp.getName()))) {
supernikita@949
   435
                            // Different name
supernikita@949
   436
                            continue;
supernikita@949
   437
                        }
supernikita@949
   438
                        if (!(soughtNamespace.equals(pseudoComp.getNamespace()))) {
supernikita@949
   439
                            // different namespace
supernikita@949
   440
                            continue;
supernikita@949
   441
                        } 
supernikita@949
   442
                        //
supernikita@949
   443
                        SchemaCompHolder compHolder = 
supernikita@949
   444
                                SchemaCompHolder.Factory.construct(pseudoComp);
supernikita@949
   445
                        result.add(compHolder);
supernikita@949
   446
                    }
supernikita@949
   447
                }
supernikita@949
   448
            }
supernikita@949
   449
        } else {
supernikita@949
   450
            convertToHolders(found, result);
supernikita@949
   451
        }
supernikita@949
   452
        //
supernikita@949
   453
        return result;
supernikita@949
   454
    }
supernikita@949
   455
    
supernikita@949
   456
    /**
supernikita@949
   457
     * Converts the list of Schema components to the list of SC holders 
supernikita@949
   458
     * @param scList
supernikita@949
   459
     * @param target
supernikita@949
   460
     */
supernikita@949
   461
    private static void convertToHolders(List<SchemaComponent> scList, 
supernikita@949
   462
            ArrayList<SchemaCompHolder> target) {
supernikita@949
   463
        for (SchemaComponent sc : scList) {
supernikita@949
   464
            SchemaCompHolder newHolder = SchemaCompHolder.Factory.construct(sc);
supernikita@949
   465
            if (newHolder != null) {
supernikita@949
   466
                target.add(newHolder);
supernikita@949
   467
            }
supernikita@949
   468
        }
supernikita@949
   469
    }
supernikita@1305
   470
supernikita@1305
   471
    /**
supernikita@1305
   472
     * Check if the input schema context is wrapping context, then takes 
supernikita@1305
   473
     * unwrapped context recursively. 
supernikita@1305
   474
     *
supernikita@1305
   475
     * @param sContext
supernikita@1305
   476
     * @return
supernikita@1305
   477
     */
supernikita@1305
   478
    public static XPathSchemaContext unwrap(XPathSchemaContext sContext) {
supernikita@1305
   479
       if (sContext instanceof WrappingSchemaContext) {
supernikita@1305
   480
           sContext = ((WrappingSchemaContext)sContext).getBaseContext();
supernikita@1305
   481
           return unwrap(sContext);
supernikita@1305
   482
       } else {
supernikita@1305
   483
           return sContext;
supernikita@1305
   484
       }
supernikita@1305
   485
    }
supernikita@1305
   486
yaroslavskiy@641
   487
}