Coverage report

  %line %branch
tsukuba_bunko.peko.scenario.PSMLUtil
25% 
58% 

 1  
 /*
 2  
  * "Peko" Visual Novel System
 3  
  *
 4  
  * All Rights Reserved.
 5  
  * Copyright (c) 1999-2003 Tsukuba Bunko.
 6  
  *
 7  
  * $Id: PSMLUtil.java,v 1.1 2005/07/11 12:49:18 ppoi Exp $
 8  
  */
 9  
 package tsukuba_bunko.peko.scenario;
 10  
 
 11  
 import	java.util.StringTokenizer;
 12  
 
 13  
 import	org.xml.sax.Attributes;
 14  
 
 15  
 import	tsukuba_bunko.peko.Logger;
 16  
 
 17  
 import	tsukuba_bunko.peko.scenario.SceneContext;
 18  
 
 19  
 
 20  
 /**
 21  
  * PSML の処理に必要なユーティリティメソッドを提供します。
 22  
  * @author	$Author: ppoi $
 23  
  * @version	$Revision: 1.1 $
 24  
  */
 25  
 public final class PSMLUtil	{
 26  
 
 27  
 	/**
 28  
 	 * <code>PSMLUtil</code> のインスタンスは生成できません。
 29  
 	 */
 30  
 	private PSMLUtil()
 31  0
 	{
 32  0
 	}
 33  
 
 34  
 
 35  
 	/**
 36  
 	 * ISO 制御文字を除去します。
 37  
 	 * @param	string	除去対象の文字列
 38  
 	 * @return	除去処理後の文字列
 39  
 	 */
 40  
 	public static String removeISOControlChar( String string )
 41  
 	{
 42  25
 		if( (string == null) || (string.length() == 0) )	{
 43  0
 			return string;
 44  
 		}
 45  
 
 46  25
 		int	beginIndex = -1;
 47  25
 		boolean	isISOControlCharSequence = false;
 48  
 
 49  25
 		int	length = string.length();
 50  25
 		StringBuffer	buffer = null;
 51  620
 		for( int current = 0; current < length; ++current )	{
 52  595
 			if( Character.isISOControl(string.charAt(current)) )	{
 53  155
 				if( !isISOControlCharSequence )	{
 54  60
 					if( buffer == null )	{
 55  20
 						if( current == 0 )	{
 56  15
 							buffer = new StringBuffer();
 57  15
 						}
 58  
 						else	{
 59  5
 							buffer = new StringBuffer( string.substring(0, current) );
 60  
 						}
 61  5
 					}
 62  
 					else	{
 63  40
 						buffer.append( string.substring(beginIndex, current) );
 64  
 					}
 65  60
 					isISOControlCharSequence = true;
 66  60
 					beginIndex = -1;
 67  60
 				}
 68  
 			}
 69  
 			else	{
 70  440
 				if( isISOControlCharSequence )	{
 71  45
 					beginIndex = current;
 72  45
 					isISOControlCharSequence = false;
 73  
 				}
 74  
 			}
 75  
 		}
 76  25
 		if( beginIndex != -1 )	{
 77  5
 			buffer.append( string.substring(beginIndex) );
 78  
 		}
 79  
 
 80  25
 		if( buffer != null )	{
 81  20
 			return new String( buffer );
 82  
 		}
 83  
 		else	{
 84  5
 			return string;
 85  
 		}
 86  
 	}
 87  
 
 88  
 
 89  
 	/**
 90  
 	 * PSML 1.0 "Scene" ネームスペース、ローカルネームスペースの順で属性値を検索します。
 91  
 	 * @param	localName	属性名のローカル名
 92  
 	 * @return	属性値。属性が定義されていない場合は <code>null</code>
 93  
 	 */
 94  
 	public static String getAttributeValue( Attributes attrs, String localName )
 95  
 	{
 96  0
 		String	value = attrs.getValue( ElementHandler.NAMESPACE_SCENE, localName );
 97  0
 		if( value == null )	{
 98  0
 			value = attrs.getValue( localName );
 99  
 		}
 100  
 
 101  0
 		if( (value == null) || (value.length() == 0) )	{
 102  0
 			return null;
 103  
 		}
 104  
 		else	{
 105  0
 			value = PSMLUtil.removeISOControlChar(value).trim();
 106  0
 			if( value.length() == 0 )	{
 107  0
 				Logger.warn( MessageIDs.SCN0011W, new Object[]{localName} );
 108  0
 				return null;
 109  
 			}
 110  
 			else	{
 111  0
 				return value;
 112  
 			}
 113  
 		}
 114  
 	}
 115  
 
 116  
 	/**
 117  
 	 * <code>attrs</code> からテストを取り出し、シナリオ文脈 <code>context</code> で評価可能かどうかを判定します。
 118  
 	 * @param	attrs	要素の属性セット
 119  
 	 * @param	context	現在のシナリオ文脈
 120  
 	 * @return	評価可能の場合 <code>true</code>、評価不可の場合 <code>false</code>
 121  
 	 */
 122  
 	public static final boolean isEvaluatable( Attributes attrs, SceneContext context )
 123  
 	{
 124  0
 		return isEvaluatable( PSMLUtil.getAttributeValue(attrs, "test"), context );
 125  
 	}
 126  
 
 127  
 	/**
 128  
 	 * <code>target</code> で指定されるテストを使用し、シナリオ文脈 <code>context</code> で評価可能かどうかを判定します。
 129  
 	 * @param	target	テスト
 130  
 	 * @param	context	現在のシナリオ文脈
 131  
 	 * @return	評価可能の場合 <code>true</code>、評価不可の場合 <code>false</code>
 132  
 	 */
 133  
 	public static final boolean isEvaluatable( String target, SceneContext context )
 134  
 	{
 135  0
 		if( (target == null) || (target.length() == 0) )	{
 136  0
 			return true;
 137  
 		}
 138  0
 		else if( context == null )	{
 139  0
 			return false;
 140  
 		}
 141  
 		else	{
 142  0
 			boolean	result = false;
 143  
 	
 144  0
 			boolean	multiple = (target.charAt(0) == '[');
 145  0
 			boolean	inBracket = false;
 146  0
 			boolean	individualResult = true;
 147  
 	
 148  0
 			StringTokenizer	st = new StringTokenizer( target, "[],", true );
 149  0
 			String	token = null;
 150  0
 			String	lastToken = null;
 151  0
 			int	position = 0;
 152  0
 			while( st.hasMoreTokens() )	{
 153  0
 				lastToken = token;
 154  0
 				token = st.nextToken();
 155  0
 				position += token.length();
 156  0
 				token = token.trim();
 157  
 	
 158  0
 				if( !multiple )	{
 159  0
 					if( "[".equals(token) || "]".equals(token) )	{
 160  0
 						Logger.warn( MessageIDs.SCN0008W, new Object[]{String.valueOf(position), token} );
 161  0
 						return false;
 162  
 					}
 163  0
 					else if( !",".equals(token) )	{
 164  0
 						if( token.charAt(0) == '!' )	{
 165  0
 							if( token.length() == 1 )	{
 166  0
 								Logger.warn( MessageIDs.SCN0008W, new Object[]{String.valueOf(position), token} );
 167  0
 								return false;
 168  
 							}
 169  0
 							token = token.substring( 1 );
 170  0
 							individualResult = individualResult && !context.isDeclaredFlag(token);
 171  0
 						}
 172  
 						else	{
 173  0
 							individualResult = individualResult && context.isDeclaredFlag(token);
 174  
 						}
 175  0
 					}
 176  
 				}
 177  
 				else	{
 178  0
 					if( inBracket )	{
 179  0
 						if( "]".equals(token) )	{
 180  0
 							if( (lastToken != null) && ",".equals(lastToken) )	{
 181  0
 								Logger.warn( MessageIDs.SCN0008W, new Object[]{String.valueOf(position), token} );
 182  0
 								return false;
 183  
 							}
 184  
 							else	{
 185  0
 								result = result || individualResult;
 186  0
 								individualResult = true;
 187  0
 								inBracket = false;
 188  
 							}
 189  0
 						}
 190  0
 						else if( !",".equals(token) )	{
 191  0
 							if( token.charAt(0) == '!' )	{
 192  0
 								if( token.length() == 1 )	{
 193  0
 									Logger.warn( MessageIDs.SCN0008W, new Object[]{String.valueOf(position), token} );
 194  0
 									return false;
 195  
 								}
 196  0
 								token = token.substring( 1 );
 197  0
 								individualResult = individualResult && !context.isDeclaredFlag(token);
 198  0
 							}
 199  
 							else	{
 200  0
 								individualResult = individualResult && context.isDeclaredFlag(token);
 201  
 							}
 202  0
 						}
 203  
 					}
 204  
 					else	{
 205  0
 						if( "[".equals(token) )	{
 206  0
 							inBracket = true;
 207  0
 						}
 208  
 						else	{
 209  0
 							Logger.warn( MessageIDs.SCN0008W, new Object[]{String.valueOf(position), token} );
 210  0
 							return false;
 211  
 						}
 212  
 					}
 213  
 				}
 214  
 			}
 215  
 	
 216  0
 			if( multiple )	{
 217  0
 				if( !"]".equals(token) )	{
 218  0
 					Logger.warn( MessageIDs.SCN0008W, new Object[]{String.valueOf(position), token} );
 219  0
 					return false;
 220  
 				}
 221  
 			}
 222  
 			else	{
 223  0
 				if( ",".equals(token) )	{
 224  0
 					Logger.warn( MessageIDs.SCN0008W, new Object[]{String.valueOf(position), token} );
 225  0
 					return false;
 226  
 				}
 227  
 				else	{
 228  0
 					result = individualResult;
 229  
 				}
 230  
 			}
 231  0
 			return result;
 232  
 		}
 233  
 	}
 234  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.