001
014
015 package com.liferay.portal.nio.intraband.proxy;
016
017 import com.liferay.portal.events.StartupHelperUtil;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.kernel.nio.intraband.RegistrationReference;
021 import com.liferay.portal.kernel.nio.intraband.rpc.IntrabandRPCUtil;
022 import com.liferay.portal.kernel.process.ProcessCallable;
023
024 import java.util.concurrent.Future;
025
026
029 public class StubHolder<T> {
030
031 public StubHolder(
032 T originalT, String stubId, RegistrationReference registrationReference,
033 StubCreator<T> stubCreator) {
034
035 _originalT = originalT;
036 _stubId = stubId;
037 _registrationReference = registrationReference;
038 _stubCreator = stubCreator;
039 }
040
041 public T getStub() {
042 if (_stub != null) {
043 return doGetStub();
044 }
045
046 synchronized (_registrationReference) {
047 if (_stub != null) {
048 return doGetStub();
049 }
050
051 Future<Boolean> future = IntrabandRPCUtil.execute(
052 _registrationReference, _startupFinishedProcessCallable);
053
054 boolean startupFinished = false;
055
056 try {
057 startupFinished = future.get();
058 }
059 catch (Exception e) {
060 if (_log.isWarnEnabled()) {
061 _log.warn("Unable to detect SPI's startup status", e);
062 }
063 }
064
065 if (!startupFinished) {
066 return _originalT;
067 }
068
069 try {
070 _stub = _stubCreator.createStub(
071 _stubId, _originalT, _registrationReference);
072
073 return _stub;
074 }
075 catch (Exception e) {
076 if (_log.isWarnEnabled()) {
077 _log.warn("Unable to create stub", e);
078 }
079
080 return _stubCreator.onCreationFailure(_stubId, _originalT, e);
081 }
082 }
083 }
084
085 public interface StubCreator<T> {
086
087 public T createStub(
088 String stubId, T originalT,
089 RegistrationReference registrationReference)
090 throws Exception;
091
092 public T onCreationFailure(String stubId, T originalT, Exception e);
093
094 public T onInvalidation(String stubId, T originalT, T stub);
095
096 }
097
098 protected T doGetStub() {
099 if (_registrationReference.isValid()) {
100 return _stub;
101 }
102
103 return _stubCreator.onInvalidation(_stubId, _stub, _originalT);
104 }
105
106 private static final Log _log = LogFactoryUtil.getLog(StubHolder.class);
107
108 private static final ProcessCallable<Boolean>
109 _startupFinishedProcessCallable = new StartupFinishedProcessCallable();
110
111 private final T _originalT;
112 private final RegistrationReference _registrationReference;
113 private volatile T _stub;
114 private final StubCreator<T> _stubCreator;
115 private final String _stubId;
116
117 private static class StartupFinishedProcessCallable
118 implements ProcessCallable<Boolean> {
119
120 @Override
121 public Boolean call() {
122 return StartupHelperUtil.isStartupFinished();
123 }
124
125 private static final long serialVersionUID = 1L;
126
127 }
128
129 }