87feea3a65fb0af843ac58a8e527b1a95ade0e7b
[scilab.git] / scilab / modules / xcos / src / java / org / scilab / modules / xcos / palette / PreLoadedElement.java
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2010 - DIGITEO - Clement DAVID
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 package org.scilab.modules.xcos.palette;
14
15 import static java.util.Arrays.asList;
16
17 import java.io.File;
18 import java.io.IOException;
19 import java.util.List;
20
21 import org.scilab.modules.types.ScilabString;
22 import org.scilab.modules.types.ScilabTList;
23 import org.scilab.modules.types.ScilabType;
24 import org.scilab.modules.xcos.io.scicos.AbstractElement;
25 import org.scilab.modules.xcos.io.scicos.ScicosFormatException;
26 import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongElementException;
27 import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongStructureException;
28 import org.scilab.modules.xcos.io.scicos.ScicosFormatException.WrongTypeException;
29 import org.scilab.modules.xcos.palette.model.PaletteBlock;
30 import org.scilab.modules.xcos.palette.model.PreLoaded;
31 import org.scilab.modules.xcos.palette.model.VariablePath;
32
33 /**
34  * Decode a palette into a {@link PreLoaded} palette.
35  */
36 public class PreLoadedElement extends AbstractElement<PreLoaded> {
37     private static final List<String> DATA_FIELD_NAMES = asList("palette",
38             "name", "blockNames", "blocks", "icons", "style");
39
40     /** Mutable field to easily get the data through methods */
41     private ScilabTList data;
42
43     /**
44      * Default constructor
45      */
46     public PreLoadedElement() {
47     }
48
49     /**
50      * Check the type name compatibility.
51      * 
52      * @param element
53      *            the current element
54      * @return <code>true</code> if the data can be decoded by this instance,
55      *         <code>false</code> otherwise.
56      * @see org.scilab.modules.xcos.io.scicos.Element#canDecode(org.scilab.modules.types.ScilabType)
57      */
58     @Override
59     public boolean canDecode(ScilabType element) {
60         data = (ScilabTList) element;
61
62         final String type = ((ScilabString) data.get(0)).getData()[0][0];
63         return type.equals(DATA_FIELD_NAMES.get(0));
64     }
65
66     /**
67      * Decode the current element on the into argument.
68      * 
69      * @param element
70      *            the Scilab data
71      * @param into
72      *            the target of the decoding (may be null)
73      * @return the filled instance
74      * @throws ScicosFormatException
75      *             on decoding error
76      * @see org.scilab.modules.xcos.io.scicos.Element#decode(org.scilab.modules.types.ScilabType,
77      *      java.lang.Object)
78      */
79     @Override
80     public PreLoaded decode(ScilabType element, PreLoaded into)
81             throws ScicosFormatException {
82         data = (ScilabTList) element;
83         PreLoaded palette = into;
84
85         validate();
86
87         if (into == null) {
88             palette = new PreLoaded();
89         }
90
91         palette.setEnable(true);
92
93         /*
94          * get the data
95          */
96
97         int field = 1;
98         String[][] name = ((ScilabString) data.get(field)).getData();
99
100         field++;
101         String[][] blockNames = ((ScilabString) data.get(field)).getData();
102
103         field++;
104         String[][] blocks = ((ScilabString) data.get(field)).getData();
105
106         field++;
107         String[][] icons = ((ScilabString) data.get(field)).getData();
108
109         /*
110          * Configure the current palette instance
111          */
112
113         palette.setName(name[0][0]);
114
115         final List<PaletteBlock> paletteBlocks = palette.getBlock();
116         for (int i = 0; i < blockNames.length; i++) {
117             for (int j = 0; j < blockNames[i].length; j++) {
118                 PaletteBlock current = new PaletteBlock();
119                 current.setName(blockNames[i][j]);
120
121                 VariablePath dataPath = new VariablePath();
122                 dataPath.setVariable(null);
123                 dataPath.setPath(blocks[i][j]);
124                 current.setData(dataPath);
125
126                 VariablePath iconPath = new VariablePath();
127                 iconPath.setVariable(null);
128                 File icon = new File(icons[i][j]);
129                 if (!icon.exists()) {
130                     try {
131                         Palette.generatePaletteIcon(blocks[i][j], icons[i][j]);
132                     } catch (IOException e) {
133                         throw new WrongTypeException(e);
134                     }
135                 }
136                 iconPath.setPath(icons[i][j]);
137                 current.setIcon(iconPath);
138
139                 paletteBlocks.add(current);
140             }
141         }
142
143         return palette;
144     }
145
146     /**
147      * Validate the current data.
148      * 
149      * This method doesn't pass the metrics because it perform many test.
150      * Therefore all these tests are trivial and the conditioned action only
151      * throw an exception.
152      * 
153      * @throws ScicosFormatException
154      *             when there is a validation error.
155      */
156     // CSOFF: CyclomaticComplexity
157     // CSOFF: NPathComplexity
158     private void validate() throws ScicosFormatException {
159         if (!canDecode(data)) {
160             throw new WrongElementException();
161         }
162
163         int field = 0;
164
165         // we test if the structure as enough field
166         if (data.size() != DATA_FIELD_NAMES.size()) {
167             throw new WrongStructureException(DATA_FIELD_NAMES);
168         }
169
170         /*
171          * Checking the TList header
172          */
173
174         // Check the first field
175         if (!(data.get(field) instanceof ScilabString)) {
176             throw new WrongTypeException(DATA_FIELD_NAMES, field);
177         }
178         final String[] header = ((ScilabString) data.get(field)).getData()[0];
179
180         // Checking for the field names
181         if (header.length != DATA_FIELD_NAMES.size()) {
182             throw new WrongStructureException(DATA_FIELD_NAMES);
183         }
184         for (int i = 0; i < header.length; i++) {
185             if (!header[i].equals(DATA_FIELD_NAMES.get(i))) {
186                 throw new WrongStructureException(DATA_FIELD_NAMES);
187             }
188         }
189
190         /*
191          * Checking the data
192          */
193
194         // the second field must contain the palette name.
195         field++;
196         if (!(data.get(field) instanceof ScilabString)
197                 || data.get(field).getWidth() != 1
198                 || data.get(field).getHeight() != 1) {
199             throw new WrongTypeException(DATA_FIELD_NAMES, field);
200         }
201
202         // the third field must contains the block name (row column)
203         field++;
204         if (!(data.get(field) instanceof ScilabString)
205                 || data.get(field).getWidth() != 1) {
206             throw new WrongTypeException(DATA_FIELD_NAMES, field);
207         }
208
209         // the fourth field must contains the block instance path (row column)
210         field++;
211         if (!(data.get(field) instanceof ScilabString)
212                 || data.get(field).getWidth() != 1) {
213             throw new WrongTypeException(DATA_FIELD_NAMES, field);
214         }
215
216         // the fifth field must contains the block icon path (row column)
217         field++;
218         if (!(data.get(field) instanceof ScilabString)
219                 || data.get(field).getWidth() != 1) {
220             throw new WrongTypeException(DATA_FIELD_NAMES, field);
221         }
222
223         // the sixth field is handled by the StyleElement decoder.
224     }
225
226     /**
227      * Not implemented yet, always return null.
228      * 
229      * @param from
230      *            the source
231      * @param element
232      *            the destination
233      * @return null
234      * @see org.scilab.modules.xcos.io.scicos.Element#encode(java.lang.Object,
235      *      org.scilab.modules.types.ScilabType)
236      */
237     @Override
238     @Deprecated
239     public ScilabType encode(PreLoaded from, ScilabType element) {
240         return null;
241     }
242
243 }