/**
* Copyright (C) 2011 Brian Ferris <bdferris@onebusaway.org>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onebusaway.users.impl;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.concurrent.atomic.AtomicInteger;
import org.onebusaway.users.model.User;
import org.onebusaway.users.model.UserIndex;
import org.onebusaway.users.model.UserProperties;
import org.onebusaway.users.model.UserPropertiesV1;
import org.onebusaway.users.model.properties.UserPropertiesV2;
import org.onebusaway.users.services.UserPropertiesService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedResource;
@ManagedResource("org.onebusaway.users.impl:name=UserPropertiesServiceVersionedInvocationHandler")
public class UserPropertiesServiceVersionedInvocationHandler implements InvocationHandler {
private static Logger _log = LoggerFactory.getLogger(UserPropertiesServiceVersionedInvocationHandler.class);
private UserPropertiesService _userServiceV1;
private UserPropertiesService _userServiceV2;
private int _preferredVersion = -1;
private AtomicInteger _v1References = new AtomicInteger();
private AtomicInteger _v2References = new AtomicInteger();
public void setUserPropertiesServiceV1(UserPropertiesService userServiceV1) {
_userServiceV1 = userServiceV1;
}
public void setUserPropertiesServiceV2(UserPropertiesService userServiceV2) {
_userServiceV2 = userServiceV2;
}
public void setPreferredVersion(int preferredVersion) {
_preferredVersion = preferredVersion;
}
@ManagedAttribute
public int getV1References() {
return _v1References.get();
}
@ManagedAttribute
public int getV2References() {
return _v2References.get();
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
UserPropertiesService service = getServiceForUserArgs(args);
return method.invoke(service, args);
}
private UserPropertiesService getServiceForUserArgs(Object[] args) {
if (_preferredVersion != -1)
return getServiceForVersion(_preferredVersion);
int maxVersion = 0;
if (args != null) {
for (Object arg : args) {
if (arg instanceof User) {
User user = (User) arg;
int version = getPropertiesVersion(user);
maxVersion = Math.max(maxVersion, version);
} else if (arg instanceof UserIndex) {
UserIndex userIndex = (UserIndex) arg;
int version = getPropertiesVersion(userIndex.getUser());
maxVersion = Math.max(maxVersion, version);
}
}
}
return getServiceForVersion(maxVersion);
}
private int getPropertiesVersion(User user) {
UserProperties props = user.getProperties();
if (props instanceof UserPropertiesV1)
return 1;
if (props instanceof UserPropertiesV2)
return 2;
_log.warn("unknown user properties version: " + props.getClass());
return 0;
}
private UserPropertiesService getServiceForVersion(int maxVersion) {
switch (maxVersion) {
case 1:
default:
_v1References.incrementAndGet();
return _userServiceV1;
case 2:
_v2References.incrementAndGet();
return _userServiceV2;
}
}
}