Coverage Report - org.semispace.ws.client.SemiSpaceTokenProxy
 
Classes in this File Line Coverage Branch Coverage Complexity
SemiSpaceTokenProxy
0%
0/75
0%
0/12
1.857
 
 1  
 /*
 2  
  * ============================================================================
 3  
  *
 4  
  *  File:     SemiSpaceTokenProxy.java
 5  
  *----------------------------------------------------------------------------
 6  
  *
 7  
  * Copyright 2008 Erlend Nossum
 8  
  *
 9  
  * Licensed under the Apache License, Version 2.0 (the "License"); 
 10  
  * you may not use this file except in compliance with the License. 
 11  
  * You may obtain a copy of the License at 
 12  
  *
 13  
  *   http://www.apache.org/licenses/LICENSE-2.0
 14  
  *
 15  
  * Unless required by applicable law or agreed to in writing, software
 16  
  * distributed under the License is distributed on an "AS IS" BASIS,
 17  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 18  
  * See the License for the specific language governing permissions and 
 19  
  * limitations under the License.
 20  
  *
 21  
  *  Description:  See javadoc below
 22  
  *
 23  
  *  Created:      Oct 19, 2008
 24  
  * ============================================================================ 
 25  
  */
 26  
 
 27  
 package org.semispace.ws.client;
 28  
 
 29  
 import javax.xml.namespace.QName;
 30  
 import javax.xml.ws.Service;
 31  
 import javax.xml.ws.soap.SOAPBinding;
 32  
 
 33  
 import org.slf4j.Logger;
 34  
 import org.slf4j.LoggerFactory;
 35  
 import org.semispace.SemiEventListener;
 36  
 import org.semispace.SemiEventRegistration;
 37  
 import org.semispace.SemiLease;
 38  
 import org.semispace.SemiSpaceInterface;
 39  
 import org.semispace.ws.TokenWsSpace;
 40  
 import org.springframework.context.support.ClassPathXmlApplicationContext;
 41  
 
 42  
 import com.thoughtworks.xstream.XStream;
 43  
 
 44  
 public class SemiSpaceTokenProxy implements SemiSpaceInterface {
 45  0
     private static final Logger log = LoggerFactory.getLogger( SemiSpaceTokenProxy.class );
 46  
     
 47  0
     private static SemiSpaceTokenProxy instance = null;
 48  
     private TokenWsSpace space;
 49  
     private XStream xstream;
 50  
     private String token;
 51  
 
 52  
     private String username;
 53  
     private String password;
 54  
 
 55  
     public String getUsername() {
 56  0
         return this.username;
 57  
     }
 58  
 
 59  
     public void setUsername(String username) {
 60  0
         this.username = username;
 61  0
     }
 62  
 
 63  
     public String getPassword() {
 64  0
         return this.password;
 65  
     }
 66  
 
 67  
     public void setPassword(String password) {
 68  0
         this.password = password;
 69  0
     }
 70  
 
 71  0
     private SemiSpaceTokenProxy() {
 72  0
         xstream = new XStream();
 73  0
     }
 74  
     
 75  
     /**
 76  
      * Open WS connection to the defined end point. This should be 
 77  
      * something similar to <tt>http://localhost:8080/semispace-war/services/tokenspace</tt>.
 78  
      */
 79  
     public static synchronized SemiSpaceTokenProxy retrieveSpace( String endpoint) {
 80  0
         if ( instance == null ) {
 81  0
             instance = retrieveSpace(readSpaceServiceAsStandardPort(endpoint));
 82  
             //instance = retrieveSpace(readSpaceServiceAsSpring());
 83  
         }
 84  
         
 85  0
         return instance;
 86  
     }
 87  
  
 88  
     /**
 89  
      * An alternative way of performing lookup
 90  
      */
 91  
     protected static TokenWsSpace readSpaceServiceAsSpring() {
 92  0
         ClassPathXmlApplicationContext context = 
 93  
             new ClassPathXmlApplicationContext(new String[] {"org/semispace/ws/client/tokenspace-bean.xml"});
 94  0
         TokenWsSpace hw = (TokenWsSpace) context.getBean("space");
 95  0
         return hw;
 96  
     }
 97  
     
 98  
     protected static TokenWsSpace readSpaceServiceAsStandardPort() {
 99  0
         return readSpaceServiceAsStandardPort("http://localhost:8080/semispace-war/services/tokenspace");
 100  
     }
 101  
     
 102  
     protected static TokenWsSpace readSpaceServiceAsStandardPort( String endpointAddress ) {
 103  0
          QName SERVICE_NAME = new QName("http://ws.semispace.org/", "TokenWsSpace");
 104  0
          QName PORT_NAME = new QName("http://ws.semispace.org/", "TokenWsSpacePort");
 105  
     
 106  0
         Service service = Service.create(SERVICE_NAME);
 107  
         
 108  
         // Add a port to the Service
 109  0
         service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING, endpointAddress);
 110  
         
 111  0
         TokenWsSpace hw = service.getPort(TokenWsSpace.class);
 112  0
         return hw;
 113  
     }
 114  
 
 115  
     /**
 116  
      * This is a bit roundabout, but is used for junit purposes.
 117  
      */
 118  
     protected static synchronized SemiSpaceTokenProxy retrieveSpace(TokenWsSpace space ) {
 119  0
         if ( instance == null ) {
 120  0
             instance = new SemiSpaceTokenProxy();
 121  0
             instance.space = space;
 122  
         }
 123  0
         return instance; 
 124  
     }
 125  
      
 126  
     
 127  
     /**
 128  
      * <b>Notify is illegal to use in proxy</b>
 129  
      */
 130  
     public SemiEventRegistration notify(Object template, SemiEventListener listener, long duration) {
 131  0
         throw new SemiSpaceProxyException("Illegal to use notify in token space proxy.", null);
 132  
     }
 133  
 
 134  
     public Object read(Object template, long duration) {
 135  
         String xml;
 136  
         try {
 137  0
             xml = space.read( fetchToken(), toXml( template ), duration);
 138  0
         } catch (Exception e) {
 139  0
             token = null;
 140  0
             throw new SemiSpaceProxyException("Could not read due to connection error.", e);
 141  0
         }
 142  0
         return fromXml( xml );
 143  
     }
 144  
 
 145  
     private Object fromXml(String xml) {
 146  0
         if ( xml == null ) {
 147  0
             return null;
 148  
         }
 149  0
         return xstream.fromXML(xml);
 150  
     }
 151  
 
 152  
     private String toXml(Object template) {
 153  0
         return xstream.toXML(template);
 154  
     }
 155  
 
 156  
     public Object readIfExists(Object template) {
 157  
         String xml;
 158  
         try {
 159  0
             xml = space.readIfExists( fetchToken(), toXml( template ));
 160  0
         } catch (Exception e) {
 161  0
             token = null;
 162  0
             throw new SemiSpaceProxyException("Could not read due to connection error.", e);
 163  0
         }
 164  0
         return fromXml( xml );
 165  
     }
 166  
 
 167  
     public Object take(Object template, long duration) {
 168  
         String xml;
 169  
         try {
 170  0
             xml = space.take(fetchToken(), toXml( template ), duration);
 171  0
         } catch (RuntimeException e) {
 172  0
             token = null;
 173  0
             throw new SemiSpaceProxyException("Could not take due to connection error.", e);
 174  0
         }
 175  0
         return fromXml( xml );
 176  
     }
 177  
 
 178  
     public Object takeIfExists(Object template) {
 179  
         String xml;
 180  
         try {
 181  0
             xml = space.takeIfExists(fetchToken(), toXml( template ));
 182  0
         } catch (RuntimeException e) {
 183  0
             token = null;
 184  0
             throw new SemiSpaceProxyException("Could not take due to connection error.", e);
 185  0
         }
 186  0
         return fromXml( xml );
 187  
     }
 188  
 
 189  
     /**
 190  
      * TODO Consider fixing that null is always returned.
 191  
      * @return will presently ALWAYS return null, even when operation was a success.
 192  
      * @see org.semispace.SemiSpaceInterface#write(java.lang.Object, long)
 193  
      */
 194  
     public SemiLease write(Object obj, long duration) {
 195  
         try {
 196  0
             space.write(fetchToken(), toXml(obj), duration);
 197  0
         } catch (RuntimeException e) {
 198  0
             token = null;
 199  0
             throw new SemiSpaceProxyException("Could not write due to connection error.", e);
 200  0
         }
 201  0
         return null;
 202  
     }
 203  
     
 204  
     /**
 205  
      * If a token is present, you are authenticated 
 206  
      */
 207  
     public boolean hasToken() {
 208  0
         return fetchToken() != null;
 209  
     }
 210  
 
 211  
     protected void setSpace(TokenWsSpace space) {
 212  0
         this.space = space;
 213  0
     }
 214  
 
 215  
     /**
 216  
      * If token has already been found, return it. Otherwise try to generate it
 217  
      * with the applicable call. If failure to obtain token, return null (which will
 218  
      * generate later errors.)
 219  
      */
 220  
     private String fetchToken() {
 221  0
         if ( token == null ) {
 222  
             try {
 223  0
                 token = space.login(getUsername(), getPassword());                
 224  0
             } catch (Exception e) {
 225  0
                 log.warn("Got exception trying to log in. Masked it was: "+e.getMessage());
 226  0
             }
 227  0
             if ( token == null ) {
 228  0
                 log.warn("Login unsuccessful with username "+username);
 229  
             } else {
 230  0
                 log.info("Logged in successfully with username "+username);
 231  
             }
 232  
         }
 233  0
         return token;
 234  
     }
 235  
 
 236  
 }