001 /* 002 * Copyright 2005 Stephen J. McConnell. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 013 * implied. 014 * 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package net.dpml.test.app; 020 021 import java.util.List; 022 import java.util.LinkedList; 023 import java.util.Iterator; 024 025 /** 026 * A server. 027 * 028 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a> 029 * @version 1.2.0 030 */ 031 public class DefaultServer implements Server 032 { 033 //------------------------------------------------------------------ 034 // concerns 035 //------------------------------------------------------------------ 036 037 /** 038 * The construction criteria. 039 */ 040 public interface Context 041 { 042 /** 043 * Return the port. 044 * @param defaultPort the default port 045 * @return the port. 046 */ 047 int getPort( int defaultPort ); 048 } 049 050 //------------------------------------------------------------------ 051 // state 052 //------------------------------------------------------------------ 053 054 private final int m_port; 055 056 private List m_listeners = new LinkedList(); 057 058 //------------------------------------------------------------------ 059 // constructor 060 //------------------------------------------------------------------ 061 062 /** 063 * Creation of a new singleton component instance. 064 * @param context a context implementation fullfilling the context criteria 065 */ 066 public DefaultServer( final Context context ) 067 { 068 m_port = context.getPort( 1234 ); 069 070 // setup port listener 071 } 072 073 //------------------------------------------------------------------ 074 // Server 075 //------------------------------------------------------------------ 076 077 /** 078 * Add a listener. 079 * @param listener the listener 080 */ 081 public void addListener( Listener listener ) 082 { 083 synchronized( m_listeners ) 084 { 085 if( m_listeners.contains( listener ) ) 086 { 087 throw new IllegalStateException( "Listener already registered." ); 088 } 089 m_listeners.add( listener ); 090 } 091 } 092 093 //------------------------------------------------------------------ 094 // testcase hook 095 //------------------------------------------------------------------ 096 097 /** 098 * Rather than fully implementing this component we are cheating by 099 * providing this hook so that the testcase can fire the notification. 100 * @param message the message supplied by the testcase to be forwarded 101 * by the implementation to registereed listeners 102 */ 103 public void triggerNotify( String message ) 104 { 105 synchronized( m_listeners ) 106 { 107 Iterator iterator = m_listeners.iterator(); 108 while( iterator.hasNext() ) 109 { 110 Listener listener = (Listener) iterator.next(); 111 listener.notify( message ); 112 } 113 } 114 } 115 }