1 /*****************************************************************************
2  * Licensed to the Apache Software Foundation (ASF) under one                *
3  * or more contributor license agreements.  See the NOTICE file              *
4  * distributed with this work for additional information                     *
5  * regarding copyright ownership.  The ASF licenses this file                *
6  * to you under the Apache License, Version 2.0 (the                         *
7  * "License"); you may not use this file except in compliance                *
8  * with the License.  You may obtain a copy of the License at                *
9  *                                                                           *
10  *     http://www.apache.org/licenses/LICENSE-2.0                            *
11  *                                                                           *
12  * Unless required by applicable law or agreed to in writing,                *
13  * software distributed under the License is distributed on an               *
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY                    *
15  * KIND, either express or implied.  See the License for the                 *
16  * specific language governing permissions and limitations                   *
17  * under the License.                                                        *
18  *                                                                           *
19  *                                                                           *
20  * This file is part of the BeanShell Java Scripting distribution.           *
21  * Documentation and updates may be found at http://www.beanshell.org/       *
22  * Patrick Niemeyer (pat@pat.net)                                            *
23  * Author of Learning Java, O'Reilly & Associates                            *
24  *                                                                           *
25  *****************************************************************************/
26 package bsh;
27 
28 import java.util.Hashtable;
29 
30 /**
31 
32 	@author Pat Niemeyer (pat@pat.net)
33 */
34 /*
35 	Note: which of these things should be checked at parse time vs. run time?
36 */
37 public class Modifiers implements java.io.Serializable
38 {
39 	public static final int CLASS=0, METHOD=1, FIELD=2;
40 	Hashtable modifiers;
41 
42 	/**
43 		@param context is METHOD or FIELD
44 	*/
addModifier( int context, String name )45 	public void addModifier( int context, String name )
46 	{
47 		if ( modifiers == null )
48 			modifiers = new Hashtable();
49 
50 		Object existing = modifiers.put( name, Void.TYPE/*arbitrary flag*/ );
51 		if ( existing != null )
52 			throw new IllegalStateException("Duplicate modifier: "+ name );
53 
54 		int count = 0;
55 		if ( hasModifier("private") ) ++count;
56 		if ( hasModifier("protected") ) ++count;
57 		if ( hasModifier("public") ) ++count;
58 		if ( count > 1 )
59 			throw new IllegalStateException(
60 				"public/private/protected cannot be used in combination." );
61 
62 		switch( context )
63 		{
64 		case CLASS:
65 			validateForClass();
66 			break;
67 		case METHOD:
68 			validateForMethod();
69 			break;
70 		case FIELD:
71 			validateForField();
72 			break;
73 		}
74 	}
75 
hasModifier( String name )76 	public boolean hasModifier( String name )
77 	{
78 		if ( modifiers == null )
79 			modifiers = new Hashtable();
80 		return modifiers.get(name) != null;
81 	}
82 
83 	// could refactor these a bit
validateForMethod()84 	private void validateForMethod()
85 	{
86 		insureNo("volatile", "Method");
87 		insureNo("transient", "Method");
88 	}
validateForField()89 	private void validateForField()
90 	{
91 		insureNo("synchronized", "Variable");
92 		insureNo("native", "Variable");
93 		insureNo("abstract", "Variable");
94 	}
validateForClass()95 	private void validateForClass()
96 	{
97 		validateForMethod(); // volatile, transient
98 		insureNo("native", "Class");
99 		insureNo("synchronized", "Class");
100 	}
101 
insureNo( String modifier, String context )102 	private void insureNo( String modifier, String context )
103 	{
104 		if ( hasModifier( modifier ) )
105 			throw new IllegalStateException(
106 				context + " cannot be declared '"+modifier+"'");
107 	}
108 
toString()109 	public String toString()
110 	{
111 		return "Modifiers: "+modifiers;
112 	}
113 
114 }
115