Revision 45626
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/src/main/java/org/gvsig/fmap/dal/store/jdbc2/OperationsFactory.java | ||
---|---|---|
87 | 87 |
IProjection crs |
88 | 88 |
); |
89 | 89 |
|
90 |
public FetchFeatureTypeOperation createFetchFeatureType( |
|
91 |
EditableFeatureType type, |
|
92 |
TableReference table, |
|
93 |
List<String> primaryKeys, |
|
94 |
String defaultGeometryField, |
|
95 |
IProjection crs, |
|
96 |
int geometryType, |
|
97 |
int geometrySubtype |
|
98 |
|
|
99 |
); |
|
100 |
|
|
90 | 101 |
public FetchFeatureProviderByReferenceOperation createFetchFeatureProviderByReference( |
91 | 102 |
FeatureReferenceProviderServices reference, |
92 | 103 |
FeatureType featureType, |
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/src/main/java/org/gvsig/fmap/dal/store/jdbc2/spi/operations/FetchFeatureTypeOperation.java | ||
---|---|---|
54 | 54 |
public class FetchFeatureTypeOperation extends AbstractConnectionOperation { |
55 | 55 |
private final EditableFeatureType featureType; |
56 | 56 |
protected final TableReference table; |
57 |
private final List<String> primaryKeys; |
|
58 |
private final String defaultGeometryColumn; |
|
59 |
private final IProjection crs; |
|
57 |
protected final List<String> primaryKeys; |
|
58 |
protected final String defaultGeometryColumn; |
|
59 |
protected final IProjection crs; |
|
60 |
protected final int geometryType; |
|
61 |
protected final int geometrySubtype; |
|
60 | 62 |
|
61 | 63 |
public FetchFeatureTypeOperation( |
62 | 64 |
JDBCHelper helper |
63 | 65 |
) { |
64 |
this(helper, null, null, null, null, null); |
|
66 |
this(helper, null, null, null, null, null, -1, -1);
|
|
65 | 67 |
} |
66 | 68 |
|
67 | 69 |
public FetchFeatureTypeOperation( |
... | ... | |
70 | 72 |
String defaultGeometryColumn, |
71 | 73 |
IProjection crs |
72 | 74 |
) { |
73 |
this(helper, featureType, null, null, defaultGeometryColumn, crs); |
|
75 |
this(helper, featureType, null, null, defaultGeometryColumn, crs, -1, -1);
|
|
74 | 76 |
} |
75 | 77 |
|
76 | 78 |
public FetchFeatureTypeOperation( |
... | ... | |
79 | 81 |
TableReference table, |
80 | 82 |
List<String> primaryKeys, |
81 | 83 |
String defaultGeometryColumn, |
82 |
IProjection crs |
|
84 |
IProjection crs, |
|
85 |
int geometryType, |
|
86 |
int geometrySubtype |
|
83 | 87 |
) { |
84 | 88 |
super(helper); |
85 | 89 |
this.featureType = featureType; |
... | ... | |
87 | 91 |
this.primaryKeys = primaryKeys; |
88 | 92 |
this.defaultGeometryColumn = defaultGeometryColumn; |
89 | 93 |
this.crs = crs; |
94 |
this.geometryType = geometryType; |
|
95 |
this.geometrySubtype = geometrySubtype; |
|
90 | 96 |
} |
91 | 97 |
|
92 | 98 |
@Override |
... | ... | |
183 | 189 |
} |
184 | 190 |
|
185 | 191 |
} |
186 |
|
|
187 |
if (crs != null && featureType.getDefaultGeometryAttribute() != null) { |
|
188 |
((EditableFeatureAttributeDescriptor) featureType.getDefaultGeometryAttribute()).setSRS(crs); |
|
192 |
|
|
193 |
if (featureType.getDefaultGeometryAttribute() != null) { |
|
194 |
EditableFeatureAttributeDescriptor attrGeom = (EditableFeatureAttributeDescriptor) featureType.getDefaultGeometryAttribute(); |
|
195 |
if (crs != null) { |
|
196 |
attrGeom.setSRS(crs); |
|
197 |
} |
|
198 |
if (geometryType != -1 && geometrySubtype != -1) { |
|
199 |
attrGeom.setGeometryType(geometryType, geometrySubtype); |
|
200 |
} else if (geometryType != -1) { |
|
201 |
attrGeom.setGeometryType(geometryType, attrGeom.getGeomType().getSubType()); |
|
202 |
} else if (geometrySubtype != -1) { |
|
203 |
attrGeom.setGeometryType(attrGeom.getGeomType().getType(), geometrySubtype); |
|
204 |
} |
|
189 | 205 |
} |
190 | 206 |
} |
191 | 207 |
|
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/src/main/java/org/gvsig/fmap/dal/store/jdbc2/spi/operations/OperationsFactoryBase.java | ||
---|---|---|
164 | 164 |
String defaultGeometryField, |
165 | 165 |
IProjection crs |
166 | 166 |
) { |
167 |
return createFetchFeatureType(type, table, primaryKeys, defaultGeometryField, crs, -1, -1); |
|
168 |
} |
|
169 |
|
|
170 |
@Override |
|
171 |
public FetchFeatureTypeOperation createFetchFeatureType( |
|
172 |
EditableFeatureType type, |
|
173 |
TableReference table, |
|
174 |
List<String> primaryKeys, |
|
175 |
String defaultGeometryField, |
|
176 |
IProjection crs, |
|
177 |
int geometryType, |
|
178 |
int geometrySubtype |
|
179 |
) { |
|
167 | 180 |
return new FetchFeatureTypeOperation(helper, type, table, |
168 |
primaryKeys, defaultGeometryField, crs); |
|
181 |
primaryKeys, defaultGeometryField, crs, geometryType, geometrySubtype);
|
|
169 | 182 |
} |
170 | 183 |
|
171 | 184 |
@Override |
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.jdbc/src/main/java/org/gvsig/fmap/dal/store/jdbc2/spi/JDBCStoreProviderBase.java | ||
---|---|---|
502 | 502 |
this.getOperations().createTableReference(params), |
503 | 503 |
primaryKeys, |
504 | 504 |
params.getDefaultGeometryField(), |
505 |
params.getCRS() |
|
505 |
params.getCRS(), |
|
506 |
params.getGeometryType(), |
|
507 |
params.getGeometrySubtype() |
|
506 | 508 |
); |
507 | 509 |
fetchFeatureType.perform(); |
508 | 510 |
|
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.mdb/src/main/java/org/gvsig/fmap/dal/store/mdb/operations/MDBFetchFeatureTypeOperation.java | ||
---|---|---|
79 | 79 |
TableReference table, |
80 | 80 |
List<String> primaryKeys, |
81 | 81 |
String defaultGeometryColumn, |
82 |
IProjection crs |
|
82 |
IProjection crs, |
|
83 |
int geometryType, |
|
84 |
int geometrySubtype |
|
85 |
|
|
83 | 86 |
) { |
84 |
super(helper, featureType, table, primaryKeys, defaultGeometryColumn, crs); |
|
87 |
super(helper, featureType, table, primaryKeys, defaultGeometryColumn, crs, geometryType, geometrySubtype);
|
|
85 | 88 |
} |
86 | 89 |
|
90 |
|
|
91 |
|
|
92 |
|
|
87 | 93 |
private GeometryColumnInfo getGeometryColumnInfo(String name) { |
88 | 94 |
if( geometry_column==null ) { |
89 | 95 |
geometry_column = new HashMap<>(); |
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.mdb/src/main/java/org/gvsig/fmap/dal/store/mdb/operations/MDBOperationsFactory.java | ||
---|---|---|
21 | 21 |
public FetchFeatureTypeOperation createFetchFeatureType(EditableFeatureType type, TableReference table, List<String> primaryKeys, String defaultGeometryField, IProjection crs) { |
22 | 22 |
return new MDBFetchFeatureTypeOperation( |
23 | 23 |
helper, type, table, primaryKeys, |
24 |
defaultGeometryField, crs |
|
24 |
defaultGeometryField, crs, -1, -1
|
|
25 | 25 |
); |
26 | 26 |
} |
27 |
|
|
28 |
@Override |
|
29 |
public FetchFeatureTypeOperation createFetchFeatureType(EditableFeatureType type, TableReference table, List<String> primaryKeys, String defaultGeometryField, IProjection crs, int geometryType, int geometrySubtype) { |
|
30 |
return new MDBFetchFeatureTypeOperation( |
|
31 |
helper, type, table, primaryKeys, |
|
32 |
defaultGeometryField, crs, geometryType, geometrySubtype |
|
33 |
); |
|
34 |
} |
|
35 |
|
|
36 |
|
|
27 | 37 |
// |
28 | 38 |
// @Override |
29 | 39 |
// public ListTablesOperation createListTables(int mode, JDBCStoreParameters baseParameters, boolean informationTables) { |
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.lib/src/main/java/org/gvsig/fmap/dal/store/db/DBStoreParameters.java | ||
---|---|---|
123 | 123 |
*/ |
124 | 124 |
public static final String CRS_PARAMTER_NAME = "CRS"; |
125 | 125 |
|
126 |
/** |
|
127 |
* Parameter name for <code>GeometryType</code><br> |
|
128 |
* |
|
129 |
* @see #setGeometryType(int) |
|
130 |
* @see #getGeometryType() |
|
131 |
*/ |
|
132 |
public static final String GEOMETRYTYPE_PARAMTER_NAME = "GeometryType"; |
|
126 | 133 |
/** |
134 |
* Parameter name for <code>GeometrySubtype</code><br> |
|
135 |
* |
|
136 |
* @see #setGeometrySubtype(int) |
|
137 |
* @see #getGeometrySubtype() |
|
138 |
*/ |
|
139 |
public static final String GEOMETRYSUBTYPE_PARAMTER_NAME = "GeometrySubtype"; |
|
140 |
|
|
141 |
/** |
|
127 | 142 |
* This instance contains the value of the current parameters. |
128 | 143 |
*/ |
129 | 144 |
private DelegatedDynObject parameters; |
... | ... | |
607 | 622 |
return (IProjection) getDynValue(CRS_PARAMTER_NAME); |
608 | 623 |
} |
609 | 624 |
|
625 |
public int getGeometryType() { |
|
626 |
Integer geomType = (Integer) this.getDynValue(GEOMETRYTYPE_PARAMTER_NAME); |
|
627 |
return geomType == null ? -1:geomType; |
|
628 |
} |
|
629 |
|
|
630 |
public void setGeometryType(int geometryType) { |
|
631 |
this.setDynValue(GEOMETRYTYPE_PARAMTER_NAME, geometryType); |
|
632 |
} |
|
633 |
|
|
634 |
public int getGeometrySubtype() { |
|
635 |
Integer geomSubtype = (Integer) this.getDynValue(GEOMETRYSUBTYPE_PARAMTER_NAME); |
|
636 |
return geomSubtype == null ? -1:geomSubtype; |
|
637 |
} |
|
638 |
|
|
639 |
public void setGeometrySubtype(int geometrySubtype) { |
|
640 |
this.setDynValue(GEOMETRYSUBTYPE_PARAMTER_NAME, geometrySubtype); |
|
641 |
} |
|
642 |
|
|
610 | 643 |
} |
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.db/org.gvsig.fmap.dal.db.lib/src/main/resources/org/gvsig/fmap/dal/store/db/DBParameters.xml | ||
---|---|---|
43 | 43 |
<description>Default geometry field</description> |
44 | 44 |
</field> |
45 | 45 |
|
46 |
<field name="GeometryType" type="integer" mandatory="false" defaultValue="-1" group="Basic"> |
|
47 |
<description>Geometry type</description> |
|
48 |
<availableValues> |
|
49 |
<value label="(Select an item)">-1</value> |
|
50 |
<value label="GEOMETRY">0</value> |
|
51 |
<value label="POINT">1</value> |
|
52 |
<value label="MULTIPOINT">7</value> |
|
53 |
<value label="CIRCLE">11</value> |
|
54 |
<value label="ARC">12</value> |
|
55 |
<value label="ELLIPSE">13</value> |
|
56 |
<value label="SPLINE">14</value> |
|
57 |
<value label="ELLIPTICARC">15</value> |
|
58 |
<value label="LINE">18</value> |
|
59 |
<value label="POLYGON">19</value> |
|
60 |
<value label="MULTILINE">21</value> |
|
61 |
<value label="MULTIPOLYGON">22</value> |
|
62 |
<value label="CIRCUMFERENCE">23</value> |
|
63 |
<value label="PERIELLIPSE">24</value> |
|
64 |
<value label="FILLEDSPLINE">25</value> |
|
65 |
</availableValues> |
|
66 |
</field> |
|
67 |
|
|
68 |
<field name="GeometrySubtype" type="integer" mandatory="false" defaultValue="-1" group="Basic"> |
|
69 |
<description>Geometry type</description> |
|
70 |
<availableValues> |
|
71 |
<value label="(Select an item)">-1</value> |
|
72 |
<value label="GEOM2D">0</value> |
|
73 |
<value label="GEOM3D">1</value> |
|
74 |
<value label="GEOM2DM">2</value> |
|
75 |
<value label="GEOM3DM">3</value> |
|
76 |
</availableValues> |
|
77 |
</field> |
|
78 |
|
|
46 | 79 |
<!-- Advanced --> |
47 | 80 |
<field name="CRS" type="crs" mandatory="false"> |
48 | 81 |
<description>CRS used to override the autodetection</description> |
trunk/org.gvsig.desktop/org.gvsig.desktop.plugin/org.gvsig.geodb.app/org.gvsig.geodb.app.mainplugin/src/main/java/org/gvsig/geodb/AbstractWizardDB.java | ||
---|---|---|
96 | 96 |
this.documentName = parameters.getTable(); |
97 | 97 |
this.projection = parameters.getCRS(); |
98 | 98 |
} |
99 |
|
|
100 |
public void fetch(JDBCStoreParameters parameters) { |
|
101 |
this.projection = parameters.getCRS(); |
|
102 |
} |
|
99 | 103 |
|
100 | 104 |
public String getDocumentName() { |
101 | 105 |
return this.documentName; |
... | ... | |
459 | 463 |
); |
460 | 464 |
dialog.addActionListener((ActionEvent e) -> { |
461 | 465 |
if( dialog.getAction()==WindowManager_v2.BUTTON_OK ) { |
462 |
panel.fetchParameters(info.getParameters()); |
|
466 |
JDBCStoreParameters parameters = info.getParameters(); |
|
467 |
panel.fetchParameters(parameters); |
|
468 |
info.fetch(parameters); |
|
469 |
put(info); |
|
463 | 470 |
} |
464 | 471 |
}); |
465 | 472 |
dialog.show(WindowManager.MODE.DIALOG); |
trunk/org.gvsig.desktop/org.gvsig.desktop.plugin/org.gvsig.h2spatial/org.gvsig.h2spatial.h2gis130/org.gvsig.h2spatial.h2gis130.provider/src/main/java/org/gvsig/fmap/dal/store/h2/operations/H2SpatialOperationsFactory.java | ||
---|---|---|
24 | 24 |
public FetchFeatureTypeOperation createFetchFeatureType(EditableFeatureType type, TableReference table, List<String> primaryKeys, String defaultGeometryField, IProjection crs) { |
25 | 25 |
return new H2SpatialFetchFeatureTypeOperation( |
26 | 26 |
helper, type, table, primaryKeys, |
27 |
defaultGeometryField, crs |
|
27 |
defaultGeometryField, crs, -1, -1
|
|
28 | 28 |
); |
29 | 29 |
} |
30 | 30 |
|
31 | 31 |
@Override |
32 |
public FetchFeatureTypeOperation createFetchFeatureType(EditableFeatureType type, TableReference table, List<String> primaryKeys, String defaultGeometryField, IProjection crs, int geometryType, int geometrySubtype) { |
|
33 |
return new H2SpatialFetchFeatureTypeOperation( |
|
34 |
helper, type, table, primaryKeys, |
|
35 |
defaultGeometryField, crs, geometryType, geometrySubtype |
|
36 |
); |
|
37 |
} |
|
38 |
|
|
39 |
@Override |
|
32 | 40 |
public ListTablesOperation createListTables(int mode, JDBCServerExplorerParameters serverParameters, boolean informationTables) { |
33 | 41 |
return new H2SpatialListTablesOperation(helper, mode, serverParameters, informationTables); |
34 | 42 |
} |
trunk/org.gvsig.desktop/org.gvsig.desktop.plugin/org.gvsig.h2spatial/org.gvsig.h2spatial.h2gis130/org.gvsig.h2spatial.h2gis130.provider/src/main/java/org/gvsig/fmap/dal/store/h2/operations/H2SpatialFetchFeatureTypeOperation.java | ||
---|---|---|
77 | 77 |
TableReference table, |
78 | 78 |
List<String> primaryKeys, |
79 | 79 |
String defaultGeometryColumn, |
80 |
IProjection crs |
|
80 |
IProjection crs, |
|
81 |
int geometryType, |
|
82 |
int geometrySubtype |
|
81 | 83 |
) { |
82 |
super(helper, featureType, table, primaryKeys, defaultGeometryColumn, crs); |
|
84 |
super(helper, featureType, table, primaryKeys, defaultGeometryColumn, crs, geometryType, geometrySubtype);
|
|
83 | 85 |
} |
84 | 86 |
|
85 | 87 |
private GeometryColumnInfo getGeometryColumnInfo(String name) { |
trunk/org.gvsig.desktop/org.gvsig.desktop.plugin/org.gvsig.h2spatial/org.gvsig.h2spatial.h2gis132/org.gvsig.h2spatial.h2gis132.provider/src/main/java/org/gvsig/fmap/dal/store/h2/operations/H2SpatialFetchFeatureTypeOperation.java | ||
---|---|---|
77 | 77 |
TableReference table, |
78 | 78 |
List<String> primaryKeys, |
79 | 79 |
String defaultGeometryColumn, |
80 |
IProjection crs |
|
80 |
IProjection crs, |
|
81 |
int geometryType, |
|
82 |
int geometrySubtype |
|
81 | 83 |
) { |
82 |
super(helper, featureType, table, primaryKeys, defaultGeometryColumn, crs); |
|
84 |
super(helper, featureType, table, primaryKeys, defaultGeometryColumn, crs, geometryType, geometrySubtype);
|
|
83 | 85 |
} |
84 | 86 |
|
85 | 87 |
private GeometryColumnInfo getGeometryColumnInfo(String name) { |
trunk/org.gvsig.desktop/org.gvsig.desktop.plugin/org.gvsig.h2spatial/org.gvsig.h2spatial.h2gis132/org.gvsig.h2spatial.h2gis132.provider/src/main/java/org/gvsig/fmap/dal/store/h2/operations/H2SpatialOperationsFactory.java | ||
---|---|---|
24 | 24 |
public FetchFeatureTypeOperation createFetchFeatureType(EditableFeatureType type, TableReference table, List<String> primaryKeys, String defaultGeometryField, IProjection crs) { |
25 | 25 |
return new H2SpatialFetchFeatureTypeOperation( |
26 | 26 |
helper, type, table, primaryKeys, |
27 |
defaultGeometryField, crs |
|
27 |
defaultGeometryField, crs, -1, -1
|
|
28 | 28 |
); |
29 | 29 |
} |
30 | 30 |
|
31 | 31 |
@Override |
32 |
public FetchFeatureTypeOperation createFetchFeatureType(EditableFeatureType type, TableReference table, List<String> primaryKeys, String defaultGeometryField, IProjection crs, int geometryType, int geometrySubtype) { |
|
33 |
return new H2SpatialFetchFeatureTypeOperation( |
|
34 |
helper, type, table, primaryKeys, |
|
35 |
defaultGeometryField, crs, geometryType, geometrySubtype |
|
36 |
); |
|
37 |
} |
|
38 |
|
|
39 |
@Override |
|
32 | 40 |
public ListTablesOperation createListTables(int mode, JDBCServerExplorerParameters serverParameters, boolean informationTables) { |
33 | 41 |
return new H2SpatialListTablesOperation(helper, mode, serverParameters, informationTables); |
34 | 42 |
} |
trunk/org.gvsig.desktop/org.gvsig.desktop.plugin/org.gvsig.h2spatial/org.gvsig.h2spatial.h2gis150/org.gvsig.h2spatial.h2gis150.provider/src/main/java/org/gvsig/fmap/dal/store/h2/operations/H2SpatialFetchFeatureTypeOperation.java | ||
---|---|---|
77 | 77 |
TableReference table, |
78 | 78 |
List<String> primaryKeys, |
79 | 79 |
String defaultGeometryColumn, |
80 |
IProjection crs |
|
80 |
IProjection crs, |
|
81 |
int geometryType, |
|
82 |
int geometrySubtype |
|
81 | 83 |
) { |
82 |
super(helper, featureType, table, primaryKeys, defaultGeometryColumn, crs); |
|
84 |
super(helper, featureType, table, primaryKeys, defaultGeometryColumn, crs, geometryType, geometrySubtype);
|
|
83 | 85 |
} |
84 | 86 |
|
85 | 87 |
private GeometryColumnInfo getGeometryColumnInfo(String name) { |
trunk/org.gvsig.desktop/org.gvsig.desktop.plugin/org.gvsig.h2spatial/org.gvsig.h2spatial.h2gis150/org.gvsig.h2spatial.h2gis150.provider/src/main/java/org/gvsig/fmap/dal/store/h2/operations/H2SpatialOperationsFactory.java | ||
---|---|---|
24 | 24 |
public FetchFeatureTypeOperation createFetchFeatureType(EditableFeatureType type, TableReference table, List<String> primaryKeys, String defaultGeometryField, IProjection crs) { |
25 | 25 |
return new H2SpatialFetchFeatureTypeOperation( |
26 | 26 |
helper, type, table, primaryKeys, |
27 |
defaultGeometryField, crs |
|
27 |
defaultGeometryField, crs, -1, -1
|
|
28 | 28 |
); |
29 | 29 |
} |
30 | 30 |
|
31 | 31 |
@Override |
32 |
public FetchFeatureTypeOperation createFetchFeatureType(EditableFeatureType type, TableReference table, List<String> primaryKeys, String defaultGeometryField, IProjection crs, int geometryType, int geometrySubtype) { |
|
33 |
return new H2SpatialFetchFeatureTypeOperation( |
|
34 |
helper, type, table, primaryKeys, |
|
35 |
defaultGeometryField, crs, geometryType, geometrySubtype |
|
36 |
); |
|
37 |
} |
|
38 |
|
|
39 |
@Override |
|
32 | 40 |
public ListTablesOperation createListTables(int mode, JDBCServerExplorerParameters serverParameters, boolean informationTables) { |
33 | 41 |
return new H2SpatialListTablesOperation(helper, mode, serverParameters, informationTables); |
34 | 42 |
} |
trunk/org.gvsig.desktop/pom.xml | ||
---|---|---|
2814 | 2814 |
|
2815 | 2815 |
<jython.artifactId>jython-standalone</jython.artifactId> |
2816 | 2816 |
<!-- External project versions --> |
2817 |
<gvsig.tools.version>3.0.280</gvsig.tools.version>
|
|
2817 |
<gvsig.tools.version>3.0.281-SNAPSHOT</gvsig.tools.version>
|
|
2818 | 2818 |
<gvsig.proj.version>1.0.31</gvsig.proj.version> |
2819 | 2819 |
<gvsig.projection.api.version>2.0.56</gvsig.projection.api.version> |
2820 | 2820 |
</properties> |
Also available in: Unified diff