1 /*
   2  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package com.sun.corba.se.spi.orb ;
  26 
  27 import java.util.Map ;
  28 import java.util.AbstractMap ;
  29 import java.util.Set ;
  30 import java.util.AbstractSet ;
  31 import java.util.Iterator ;
  32 import java.util.Properties ;
  33 
  34 import java.lang.reflect.Field ;
  35 
  36 import org.omg.CORBA.INTERNAL ;
  37 
  38 // XXX This could probably be further extended by using more reflection and
  39 // a dynamic proxy that satisfies the interfaces that are inherited by the
  40 // more derived class.  Do we want to go that far?
  41 public abstract class ParserImplTableBase extends ParserImplBase {
  42     private final ParserData[] entries ;
  43 
  44     public ParserImplTableBase( ParserData[] entries )
  45     {
  46         this.entries = entries ;
  47         setDefaultValues() ;
  48     }
  49 
  50     protected PropertyParser makeParser()
  51     {
  52         PropertyParser result = new PropertyParser() ;
  53         for (int ctr=0; ctr<entries.length; ctr++ ) {
  54             ParserData entry = entries[ctr] ;
  55             entry.addToParser( result ) ;
  56         }
  57 
  58         return result ;
  59     }
  60 
  61     private static final class MapEntry implements Map.Entry {
  62         private Object key ;
  63         private Object value ;
  64 
  65         public MapEntry( Object key )
  66         {
  67             this.key = key ;
  68         }
  69 
  70         public Object getKey()
  71         {
  72             return key ;
  73         }
  74 
  75         public Object getValue()
  76         {
  77             return value ;
  78         }
  79 
  80         public Object setValue( Object value )
  81         {
  82             Object result = this.value ;
  83             this.value = value ;
  84             return result ;
  85         }
  86 
  87         public boolean equals( Object obj )
  88         {
  89             if (!(obj instanceof MapEntry))
  90                 return false ;
  91 
  92             MapEntry other = (MapEntry)obj ;
  93 
  94             return (key.equals( other.key )) &&
  95                 (value.equals( other.value )) ;
  96         }
  97 
  98         public int hashCode()
  99         {
 100             return key.hashCode() ^ value.hashCode() ;
 101         }
 102     }
 103 
 104     // Construct a map that maps field names to test or default values,
 105     // then use setFields from the parent class.  A map is constructed
 106     // by implementing AbstractMap, which requires implementing the
 107     // entrySet() method, which requires implementing a set of
 108     // map entries, which requires implementing an iterator,
 109     // which iterates over the ParserData, extracting the
 110     // correct (key, value) pairs (nested typed lambda expression).
 111     private static class FieldMap extends AbstractMap {
 112         private final ParserData[] entries ;
 113         private final boolean useDefault ;
 114 
 115         public FieldMap( ParserData[] entries, boolean useDefault )
 116         {
 117             this.entries = entries ;
 118             this.useDefault = useDefault ;
 119         }
 120 
 121         public Set entrySet()
 122         {
 123             return new AbstractSet()
 124             {
 125                 public Iterator iterator()
 126                 {
 127                     return new Iterator() {
 128                         // index of next element to return
 129                         int ctr = 0 ;
 130 
 131                         public boolean hasNext()
 132                         {
 133                             return ctr < entries.length ;
 134                         }
 135 
 136                         public Object next()
 137                         {
 138                             ParserData pd = entries[ctr++] ;
 139                             Map.Entry result = new MapEntry( pd.getFieldName() ) ;
 140                             if (useDefault)
 141                                 result.setValue( pd.getDefaultValue() ) ;
 142                             else
 143                                 result.setValue( pd.getTestValue() ) ;
 144                             return result ;
 145                         }
 146 
 147                         public void remove()
 148                         {
 149                             throw new UnsupportedOperationException() ;
 150                         }
 151                     } ;
 152                 }
 153 
 154                 public int size()
 155                 {
 156                     return entries.length ;
 157                 }
 158             } ;
 159         }
 160     } ;
 161 
 162     protected void setDefaultValues()
 163     {
 164         Map map = new FieldMap( entries, true ) ;
 165         setFields( map ) ;
 166     }
 167 
 168     public void setTestValues()
 169     {
 170         Map map = new FieldMap( entries, false ) ;
 171         setFields( map ) ;
 172     }
 173 }