001/*
002 *  Copyright 2010 Anyware Services
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 */
016package org.ametys.plugins.repository.query.expression;
017
018import org.ametys.core.user.UserIdentity;
019import org.ametys.plugins.repository.RepositoryConstants;
020
021/**
022 * Constructs an {@link Expression} corresponding to a user comparison store as a composite with login and id of population.
023 */
024public class UserExpression implements Expression
025{
026    private UserIdentity _user;
027    private Operator _operator;
028    private String _metadata;
029    private boolean _unversioned;
030    private boolean _multiple;
031    
032    /**
033     * Creates the comparison Expression.
034     * @param metadata the metadata path
035     * @param operator the operator to make the comparison
036     * @param value the user identity as login#population.
037     */
038    public UserExpression(String metadata, Operator operator, String value)
039    {
040        this(metadata, operator, UserIdentity.stringToUserIdentity(value), false);
041    }
042    
043    /**
044     * Creates the comparison Expression.
045     * @param metadata the metadata path
046     * @param operator the operator to make the comparison
047     * @param value the user identity as login#population.
048     * @param multiple true if the attribute is multiple
049     */
050    public UserExpression(String metadata, Operator operator, String value, boolean multiple)
051    {
052        this(metadata, operator, UserIdentity.stringToUserIdentity(value), multiple, false);
053    }
054    
055    /**
056     * Creates the comparison Expression.
057     * @param metadata the metadata path
058     * @param operator the operator to make the comparison
059     * @param value the user identity as login#population.
060     * @param multiple true if the attribute is multiple
061     * @param unversioned true if the metadata is unversioned, false otherwise.
062     */
063    public UserExpression(String metadata, Operator operator, String value, boolean multiple, boolean unversioned)
064    {
065        this(metadata, operator, UserIdentity.stringToUserIdentity(value), multiple, unversioned);
066    }
067    
068    /**
069     * Creates the comparison Expression.
070     * @param metadata the metadata path
071     * @param operator the operator to make the comparison
072     * @param userIdentity the user identity (login and population)
073     */
074    public UserExpression(String metadata, Operator operator, UserIdentity userIdentity)
075    {
076        this(metadata, operator, userIdentity, false, false);
077    }
078    
079    /**
080     * Creates the comparison Expression.
081     * @param metadata the metadata path
082     * @param operator the operator to make the comparison
083     * @param userIdentity the user identity (login and population)
084     * @param multiple true if the attribute is multiple
085     */
086    public UserExpression(String metadata, Operator operator, UserIdentity userIdentity, boolean multiple)
087    {
088        this(metadata, operator, userIdentity, multiple, false);
089    }
090    
091    /**
092     * Creates the comparison Expression.
093     * @param metadata the metadata path
094     * @param operator the operator to make the comparison
095     * @param userIdentity the user identity (login and population)
096     * @param multiple true if the attribute is multiple
097     * @param unversioned true if the metadata is unversioned, false otherwise.
098     */
099    public UserExpression(String metadata, Operator operator, UserIdentity userIdentity, boolean multiple, boolean unversioned)
100    {
101        _user = userIdentity;
102        _metadata = metadata;
103        _unversioned = unversioned;
104        _operator = operator;
105        _multiple = multiple;
106    }
107    
108    @Override
109    public String build()
110    {
111        Expression expr = new AndExpression(new UserLoginExpression(_metadata, _operator, _user.getLogin(), _multiple, _unversioned), new UserPopulationExpression(_metadata, _operator, _user.getPopulationId(), _multiple, _unversioned));
112        return expr.build();
113    }
114    
115    /**
116     * Internal class to create a expression based on a user's login comparison
117     */
118    class UserLoginExpression implements Expression
119    {
120        private String _uleValue;
121        private Operator _uleOperator;
122        
123        private String _uleMetadata;
124        private String _ulePath;
125        private boolean _uleUnversioned;
126        private boolean _uleMultiple;
127        
128        /**
129         * Construction an expression to test a user login
130         * @param metadata The path to metadata
131         * @param operator The operator
132         * @param value The login value
133         * @param multiple true if the attribute is multiple
134         * @param unversioned unversioned true if the metadata is unversioned, false otherwise.
135         */
136        public UserLoginExpression(String metadata, Operator operator, String value, boolean multiple, boolean unversioned)
137        {
138            _uleValue = value;
139            _uleOperator = operator;
140            
141            int index = metadata.lastIndexOf('/');
142            boolean isComposite = index != -1;
143            _ulePath = isComposite ? metadata.substring(0, index) : null;
144            _uleMetadata = isComposite ? metadata.substring(index + 1) : metadata;
145            _uleUnversioned = unversioned;
146            _uleMultiple = multiple;
147        }
148        
149        @Override
150        public String build()
151        {
152            StringBuilder buff = new StringBuilder();
153            
154            if (_uleUnversioned)
155            {
156                buff.append(RepositoryConstants.NAMESPACE_PREFIX_INTERNAL).append(":unversioned/");
157            }
158            
159            if (_ulePath != null)
160            {
161                String[] parts = _ulePath.split("/");
162                for (String part : parts)
163                {
164                    if ("*".equals(part))
165                    {
166                        buff.append(part).append('/');
167                    }
168                    else
169                    {
170                        buff.append(RepositoryConstants.NAMESPACE_PREFIX).append(':').append(part).append('/');
171                    }
172                    
173                }
174            }
175            
176            buff.append(RepositoryConstants.NAMESPACE_PREFIX).append(':').append(_uleMetadata).append('/');
177            
178            if (_uleMultiple)
179            {
180                buff.append("*/");
181            }
182            
183            buff.append('@').append(RepositoryConstants.NAMESPACE_PREFIX).append(':').append("login");
184            buff.append(" " + _uleOperator);
185            buff.append(" '" + _uleValue.replaceAll("'", "''") + "'");
186            
187            return buff.toString();
188        }
189    }
190    
191    /**
192     * Internal class to create a expression based on a user's population comparison
193     */
194    class UserPopulationExpression implements Expression
195    {
196        private String _upeValue;
197        private Operator _upeOperator;
198        
199        private String _upeMetadata;
200        private String _upePath;
201        private boolean _upeUnversioned;
202        private boolean _upeMultiple;
203        
204        /**
205         * Construction an expression to test a user population
206         * @param metadata The path to metadata
207         * @param operator The operator
208         * @param value The population's id
209         * @param multiple true if the attribute is multiple
210         * @param unversioned unversioned true if the metadata is unversioned, false otherwise.
211         */
212        public UserPopulationExpression(String metadata, Operator operator, String value, boolean multiple, boolean unversioned)
213        {
214            _upeValue = value;
215            _upeOperator = operator;
216            
217            int index = metadata.lastIndexOf('/');
218            boolean isComposite = index != -1;
219            _upePath = isComposite ? metadata.substring(0, index) : null;
220            _upeMetadata = isComposite ? metadata.substring(index + 1) : metadata;
221            _upeUnversioned = unversioned;
222            _upeMultiple = multiple;
223        }
224        
225        @Override
226        public String build()
227        {
228            StringBuilder buff = new StringBuilder();
229            
230            if (_upeUnversioned)
231            {
232                buff.append(RepositoryConstants.NAMESPACE_PREFIX_INTERNAL).append(":unversioned/");
233            }
234            
235            if (_upePath != null)
236            {
237                String[] parts = _upePath.split("/");
238                for (String part : parts)
239                {
240                    if ("*".equals(part))
241                    {
242                        buff.append(part).append('/');
243                    }
244                    else
245                    {
246                        buff.append(RepositoryConstants.NAMESPACE_PREFIX).append(':').append(part).append('/');
247                    }
248                    
249                }
250            }
251            
252            buff.append(RepositoryConstants.NAMESPACE_PREFIX).append(':').append(_upeMetadata).append('/');
253            
254            if (_upeMultiple)
255            {
256                buff.append("*/");
257            }
258            
259            buff.append('@').append(RepositoryConstants.NAMESPACE_PREFIX).append(':').append("population");
260            buff.append(" " + _upeOperator);
261            buff.append(" '" + _upeValue + "'");
262            
263            return buff.toString();
264        }
265    }
266    
267    
268}