001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.nio.intraband.proxy;
016    
017    import com.liferay.portal.kernel.nio.intraband.RegistrationReference;
018    import com.liferay.portal.kernel.resiliency.spi.SPI;
019    import com.liferay.portal.kernel.resiliency.spi.SPIRegistryUtil;
020    import com.liferay.portal.nio.intraband.proxy.StubHolder.StubCreator;
021    
022    import java.rmi.RemoteException;
023    
024    import java.util.concurrent.ConcurrentHashMap;
025    import java.util.concurrent.ConcurrentMap;
026    
027    /**
028     * @author Shuyang Zhou
029     */
030    public class StubMap<T> extends ConcurrentHashMap<String, T> {
031    
032            public StubMap(StubCreator<T> stubCreator) {
033                    _stubCreator = stubCreator;
034            }
035    
036            @Override
037            public T get(Object key) {
038                    String portletId = String.valueOf(key);
039    
040                    StubHolder<T> stubHolder = _stubHolders.get(portletId);
041    
042                    if (stubHolder != null) {
043                            return stubHolder.getStub();
044                    }
045    
046                    T originalValue = super.get(key);
047    
048                    if (originalValue == null) {
049                            return null;
050                    }
051    
052                    RegistrationReference registrationReference = _getRegistrationReference(
053                            portletId);
054    
055                    if (registrationReference == null) {
056                            return originalValue;
057                    }
058    
059                    stubHolder = new StubHolder<T>(
060                            originalValue, portletId, registrationReference, _stubCreator);
061    
062                    StubHolder<T> previousStubHolder = _stubHolders.putIfAbsent(
063                            portletId, stubHolder);
064    
065                    if (previousStubHolder != null) {
066                            stubHolder = previousStubHolder;
067                    }
068    
069                    return stubHolder.getStub();
070            }
071    
072            public boolean removeStubHolder(String portletId, T stub) {
073                    return _stubHolders.remove(portletId, stub);
074            }
075    
076            private RegistrationReference _getRegistrationReference(String portletId) {
077                    SPI spi = SPIRegistryUtil.getPortletSPI(portletId);
078    
079                    if (spi == null) {
080                            return null;
081                    }
082    
083                    try {
084                            return spi.getRegistrationReference();
085                    }
086                    catch (RemoteException re) {
087                            throw new RuntimeException(re);
088                    }
089            }
090    
091            private final StubCreator<T> _stubCreator;
092            private final ConcurrentMap<String, StubHolder<T>> _stubHolders =
093                    new ConcurrentHashMap<String, StubHolder<T>>();
094    
095    }