Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.sqlite / org.gvsig.sqlite.provider / src / main / java / org / gvsig / sqlite / dal / utils / TemplateUtils.java @ 47456

History | View | Annotate | Download (6.63 KB)

1
/*
2
 * gvSIG. Desktop Geographic Information System.
3
 * 
4
 * Copyright (C) 2007-2023 gvSIG Association.
5
 * 
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 * 
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 * 
16
 * You should have received a copy of the GNU General Public License 
17
 * along with this program. If not, see <https://www.gnu.org/licenses/>. 
18
 * 
19
 * For any additional information, do not hesitate to contact us
20
 * at info AT gvsig.com, or visit our website www.gvsig.com.
21
 */
22

    
23
package org.gvsig.sqlite.dal.utils;
24

    
25
import java.io.IOException;
26
import java.io.InputStream;
27
import java.util.ArrayList;
28
import java.util.HashMap;
29
import java.util.List;
30
import java.util.Map;
31
import org.apache.commons.io.IOUtils;
32
import org.apache.commons.lang3.ArrayUtils;
33
import org.apache.commons.lang3.StringUtils;
34
import org.slf4j.Logger;
35
import org.slf4j.LoggerFactory;
36

    
37
/**
38
 *
39
 * @author gvSIG Team
40
 */
41
@SuppressWarnings("UseSpecificCatch")
42
public class TemplateUtils {
43
    
44
    private static final Logger LOGGER = LoggerFactory.getLogger(TemplateUtils.class);
45

    
46
    private static final Map<String, Map<String, Template>> SQL_TEMPLATES_BY_GROUP = new HashMap<>();
47
    
48
    private static final String TEMPLATES_FOLDER = "/org/gvsig/sqlite/dal/sqltemplates/";
49
    
50
    private static class Template {
51
        List<String> parameters;
52
        Map<String,String> constants;
53
        String code;
54
        String name;
55
        
56
        public Template(String name) {
57
            this.name = name;
58
            this.parameters = new ArrayList<>();
59
            this.constants = new HashMap<>();
60
            this.code = null;
61
        }
62
        
63
        public void setCode(String code) {
64
            this.code = code;
65
        }
66
        
67
        public void addParameter(String parameter) {
68
            this.parameters.add(parameter);
69
        }
70
        
71
        public void addConstant(String name, String value) {
72
            this.constants.put(name, value);
73
        }
74
        
75
        public String getName() {
76
            return this.name;
77
        }
78
        
79
        public String getCode(Object...params) {
80
            if( this.parameters.isEmpty() ) {
81
                return String.format(this.code, params);
82
            }
83
            String s = this.code;
84
            for (int i = 0; i < parameters.size(); i++) {
85
                s = s.replace("%"+parameters.get(i)+"$", "%"+(i+1)+"$");
86
            }
87
            for (Map.Entry<String, String> entry : constants.entrySet()) {
88
                String cname = entry.getKey();
89
                String cvalue = entry.getValue();
90
                s = s.replace("%"+cname+"$s", cvalue);
91
            }
92
            if( ArrayUtils.isEmpty(params) ) {
93
                return s;
94
            }
95
            s = String.format(s, params);
96
            return s;
97
        }
98

    
99
        @Override
100
        public String toString() {
101
            return this.name;
102
        }
103
        
104
    }
105
    
106
    @SuppressWarnings("null")
107
    private static Map<String,Template> getSqlTemplates(String group) {
108
      final int SEARCHING_ITEM = 0;
109
      final int READING_ITEM = 1;
110
      
111
      InputStream sqls = TemplateUtils.class.getResourceAsStream(TEMPLATES_FOLDER+group+".sql"); 
112
      Map<String,Template> expecteds = new HashMap<>();
113
      List<String> lines;
114
        try {
115
            lines = IOUtils.readLines(sqls);
116
        } catch (IOException ex) {
117
            throw new RuntimeException("Can't read sql templates for group "+group, ex);
118
        }
119

    
120
      StringBuilder sb = null;
121
      Template currentItem = null;
122
      int lineno = 1;
123
      int state = SEARCHING_ITEM;
124
      for (String line : lines) {
125
          line = line + "\n";
126
          switch(state) {
127
            case SEARCHING_ITEM:
128
                if( line.toLowerCase().startsWith("@begin ") ) {
129
                    currentItem = new Template(line.substring(7).trim());
130
                    sb = new StringBuilder();
131
                    state = READING_ITEM;
132
                } else if( line.toLowerCase().startsWith("-- ") || line.toLowerCase().startsWith("@rem") ) {
133
                    // do nothing skip comment
134
                } else if( !StringUtils.isBlank(line) ) {
135
                    throw new IllegalStateException("Syntax error at '"+group+"', line "+lineno+ ".");
136
                }
137
                break;
138
            case READING_ITEM:
139
                if( line.toLowerCase().startsWith("@end ") ) {
140
                    String found = line.substring(5).trim();
141
                    if( !StringUtils.equals(currentItem.getName(),found) ) {
142
                      throw new IllegalStateException("Syntax error at '"+group+"', line "+lineno+ ", expected @end "+currentItem.getName()+", and found "+line+".");
143
                    }
144
                    String s = sb.toString();
145
                    if( s.endsWith("\n") ) {
146
                        s = s.substring(0, s.length()-1);
147
                    }
148
                    currentItem.setCode(s);
149
                    expecteds.put(currentItem.getName(), currentItem);
150
                    state = SEARCHING_ITEM;
151
                    
152
                } else if( line.toLowerCase().startsWith("-- ") || line.toLowerCase().startsWith("@rem") ) {
153
                    // do nothing skip comment
154
                } else if( line.toLowerCase().startsWith("@param ") ) {
155
                    currentItem.addParameter(line.substring(7).trim());
156
                } else if( line.toLowerCase().startsWith("@const ") ) {
157
                    String s = line.substring(7).trim();
158
                    String[] ss = StringUtils.split(s, "=");
159
                    currentItem.addConstant(ss[0].trim(),ss[1].trim());
160
                } else {
161
                    sb.append(line);
162
                }
163
                break;
164
        }
165
        lineno++;
166
      }
167
      if( state!=SEARCHING_ITEM ) {
168
          throw new IllegalStateException("Syntax error at '"+group+"', expected @end "+currentItem.getName()+" and found EOF .");
169
      }
170
      return expecteds;
171
    }
172
    
173
    public static String getSqlTemplate(String group, String sqlId, Object... args){
174
        if(SQL_TEMPLATES_BY_GROUP.get(group) == null) {
175
            SQL_TEMPLATES_BY_GROUP.put(group, getSqlTemplates(group));
176
        }
177
        Template template = SQL_TEMPLATES_BY_GROUP.get(group).get(sqlId);
178
        if( template==null ) {
179
            return null;
180
        }
181
        return template.getCode(args);
182
    }
183
    
184
}