001/*
002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Anahide Tchertchian
018 */
019package org.nuxeo.ecm.platform.forms.layout.facelets;
020
021import java.io.Serializable;
022import java.util.Collections;
023import java.util.HashMap;
024import java.util.Map;
025
026import org.apache.commons.logging.Log;
027import org.apache.commons.logging.LogFactory;
028
029/**
030 * Request-scoped bean keeping generated ids counters and logics for layouts and widgets.
031 *
032 * @since 7.2
033 */
034public class NuxeoLayoutIdManagerBean implements Serializable {
035
036    private static final long serialVersionUID = 1L;
037
038    public static final String NAME = "nuxeoLayoutIdManager";
039
040    private static final Log log = LogFactory.getLog(NuxeoLayoutIdManagerBean.class);
041
042    protected Map<String, State> ids;
043
044    public NuxeoLayoutIdManagerBean() {
045        super();
046    }
047
048    public String generateUniqueId(String base) {
049        String res;
050        // strip base of any remnant counter name
051        String bareBase = FaceletHandlerHelper.stripUniqueIdBase(FaceletHandlerHelper.generateValidIdString(base));
052        Integer count = 0;
053        if (ids != null && ids.containsKey(bareBase)) {
054            State state = ids.get(bareBase);
055            count = state.getCounter() + 1;
056            setCounter(bareBase, count);
057            res = bareBase + "_" + count;
058        } else {
059            res = bareBase;
060            setCounter(bareBase, count);
061        }
062        if (log.isDebugEnabled()) {
063            log.debug(String.format("Computed id='%s' for base='%s'", res, bareBase));
064        }
065        return res;
066    }
067
068    public Map<String, State> getIds() {
069        return Collections.unmodifiableMap(ids);
070    }
071
072    public void resetIds() {
073        ids = null;
074    }
075
076    protected void setCounter(String id, Integer count) {
077        if (ids == null) {
078            ids = new HashMap<>();
079        }
080        State state;
081        if (ids.containsKey(id)) {
082            state = ids.get(id);
083        } else {
084            state = new State();
085            ids.put(id, state);
086        }
087        state.setCounter(count);
088    }
089
090    private static final class State implements Serializable {
091
092        private static final long serialVersionUID = 1L;
093
094        protected Integer counter;
095
096        public Integer getCounter() {
097            return counter;
098        }
099
100        public void setCounter(Integer counter) {
101            this.counter = counter;
102        }
103
104        @Override
105        public String toString() {
106            final StringBuilder buf = new StringBuilder();
107
108            buf.append("State");
109            buf.append(" {");
110            buf.append(" counter=");
111            buf.append(counter);
112            buf.append('}');
113
114            return buf.toString();
115        }
116
117    }
118
119}