001/*
002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl-2.1.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Anahide Tchertchian
016 */
017package org.nuxeo.ecm.platform.forms.layout.facelets;
018
019import java.io.Serializable;
020import java.util.Collections;
021import java.util.HashMap;
022import java.util.Map;
023
024import org.apache.commons.logging.Log;
025import org.apache.commons.logging.LogFactory;
026
027/**
028 * Request-scoped bean keeping generated ids counters and logics for layouts and widgets.
029 *
030 * @since 7.2
031 */
032public class NuxeoLayoutIdManagerBean implements Serializable {
033
034    private static final long serialVersionUID = 1L;
035
036    public static final String NAME = "nuxeoLayoutIdManager";
037
038    private static final Log log = LogFactory.getLog(NuxeoLayoutIdManagerBean.class);
039
040    protected Map<String, State> ids;
041
042    public NuxeoLayoutIdManagerBean() {
043        super();
044    }
045
046    public String generateUniqueId(String base) {
047        String res;
048        // strip base of any remnant counter name
049        String bareBase = FaceletHandlerHelper.stripUniqueIdBase(FaceletHandlerHelper.generateValidIdString(base));
050        Integer count = 0;
051        if (ids != null && ids.containsKey(bareBase)) {
052            State state = ids.get(bareBase);
053            count = state.getCounter() + 1;
054            setCounter(bareBase, count);
055            res = bareBase + "_" + count;
056        } else {
057            res = bareBase;
058            setCounter(bareBase, count);
059        }
060        if (log.isDebugEnabled()) {
061            log.debug(String.format("Computed id='%s' for base='%s'", res, bareBase));
062        }
063        return res;
064    }
065
066    public Map<String, State> getIds() {
067        return Collections.unmodifiableMap(ids);
068    }
069
070    public void resetIds() {
071        ids = null;
072    }
073
074    protected void setCounter(String id, Integer count) {
075        if (ids == null) {
076            ids = new HashMap<>();
077        }
078        State state;
079        if (ids.containsKey(id)) {
080            state = ids.get(id);
081        } else {
082            state = new State();
083            ids.put(id, state);
084        }
085        state.setCounter(count);
086    }
087
088    private static final class State implements Serializable {
089
090        private static final long serialVersionUID = 1L;
091
092        protected Integer counter;
093
094        public Integer getCounter() {
095            return counter;
096        }
097
098        public void setCounter(Integer counter) {
099            this.counter = counter;
100        }
101
102        @Override
103        public String toString() {
104            final StringBuilder buf = new StringBuilder();
105
106            buf.append("State");
107            buf.append(" {");
108            buf.append(" counter=");
109            buf.append(counter);
110            buf.append('}');
111
112            return buf.toString();
113        }
114
115    }
116
117}