001// Generated by delombok at Mon Oct 02 22:22:47 BST 2023
002/*
003 *  Licensed to the Apache Software Foundation (ASF) under one
004 *  or more contributor license agreements.  See the NOTICE file
005 *  distributed with this work for additional information
006 *  regarding copyright ownership.  The ASF licenses this file
007 *  to you under the Apache License, Version 2.0 (the
008 *  "License"); you may not use this file except in compliance
009 *  with the License.  You may obtain a copy of the License at
010 *
011 *        http://www.apache.org/licenses/LICENSE-2.0
012 *
013 *  Unless required by applicable law or agreed to in writing,
014 *  software distributed under the License is distributed on an
015 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 *  KIND, either express or implied.  See the License for the
017 *  specific language governing permissions and limitations
018 *  under the License.
019 */
020package org.apache.causeway.extensions.excel.testing;
021
022import java.io.InputStream;
023import java.net.URL;
024import java.util.Arrays;
025import java.util.List;
026import javax.inject.Inject;
027import javax.inject.Named;
028import org.apache.causeway.applib.annotation.DomainObject;
029import org.apache.causeway.applib.annotation.Programmatic;
030import org.apache.causeway.applib.annotation.PropertyLayout;
031import org.apache.causeway.applib.services.factory.FactoryService;
032import org.apache.causeway.applib.value.Blob;
033import org.apache.causeway.commons.internal.base._Bytes;
034import org.apache.causeway.extensions.excel.applib.CausewayModuleExtExcelApplib;
035import org.apache.causeway.extensions.excel.applib.ExcelService;
036import org.apache.causeway.extensions.excel.applib.WorksheetSpec;
037import org.apache.causeway.testing.fixtures.applib.fixturescripts.FixtureScript;
038import org.apache.causeway.testing.fixtures.applib.fixturescripts.FixtureScriptWithExecutionStrategy;
039import org.apache.causeway.testing.fixtures.applib.fixturescripts.FixtureScripts;
040
041/**
042 * @since 2.0 {@index}
043 */
044@Named(ExcelFixture2.LOGICAL_TYPE_NAME)
045@DomainObject
046public class ExcelFixture2 extends FixtureScript implements FixtureScriptWithExecutionStrategy {
047    public static final String LOGICAL_TYPE_NAME = CausewayModuleExtExcelApplib.NAMESPACE + ".ExcelFixture2";
048    @Inject
049    FactoryService factoryService;
050    @Inject
051    ExcelService excelService;
052    /**
053     * Input, optional: defines the name of the resource.
054     */
055    @PropertyLayout(sequence = "1.1")
056    private String excelResourceName;
057    /**
058     * Input, either this or the blob is mandatory ... the Excel spreadsheet to read.
059     */
060    @PropertyLayout(sequence = "1.2")
061    private URL excelResource;
062    /**
063     * Input, either this or the excelResource is mandatory ... the Excel spreadsheet to read.
064     */
065    private Blob blob;
066    /**
067     * Input, mandatory ... how to process each sheet of the workbook.
068     */
069    WorksheetSpec.Matcher matcher;
070    /**
071     * Input, optional ... which sequence to process the matched sheets
072     */
073    private WorksheetSpec.Sequencer sequencer;
074
075    protected <T> WorksheetSpec.RowFactory<T> rowFactoryFor(final Class<T> rowClass, final ExecutionContext ec) {
076        return new WorksheetSpec.RowFactory<T>() {
077            @Override
078            public T create() {
079                final T importLine = factoryService.getOrCreate(rowClass);
080                // allow the line to interact with the calling fixture
081                if (importLine instanceof FixtureAwareRowHandler<?>) {
082                    final FixtureAwareRowHandler<?> farh = (FixtureAwareRowHandler<?>) importLine;
083                    farh.setExecutionContext(ec);
084                    farh.setExcelFixture2(ExcelFixture2.this);
085                }
086                return importLine;
087            }
088            @Override
089            public Class<?> getCls() {
090                return rowClass;
091            }
092        };
093    }
094
095    // list of list not allowed to enter meta-model
096    /**
097     * Output... a list of list of objects (each representing a row of a sheet)
098     */
099    @Programmatic
100    private List<List<?>> lists;
101
102    @Override
103    protected void execute(final ExecutionContext executionContext) {
104        if (blob == null) {
105            byte[] bytes = getBytes();
106            blob = new Blob("unused", ExcelService.XSLX_MIME_TYPE, bytes);
107        }
108        this.lists = excelService.fromExcel(blob, matcher, sequencer);
109    }
110
111    private byte[] bytes;
112
113    private byte[] getBytes() {
114        if (bytes == null) {
115            if (blob != null) {
116                bytes = blob.getBytes();
117            } else {
118                bytes = readBytes();
119            }
120        }
121        return bytes;
122    }
123
124    private byte[] readBytes() {
125        try (InputStream is = getExcelResource().openStream()) {
126            return _Bytes.of(is);
127        } catch (Exception e) {
128            throw new IllegalArgumentException("Could not read from resource: " + getExcelResource());
129        }
130    }
131
132    @Override
133    public FixtureScripts.MultipleExecutionStrategy getMultipleExecutionStrategy() {
134        return FixtureScripts.MultipleExecutionStrategy.EXECUTE_ONCE_BY_VALUE;
135    }
136
137    @Override
138    public boolean equals(final Object o) {
139        if (this == o) return true;
140        if (o == null || getClass() != o.getClass()) return false;
141        final ExcelFixture2 that = (ExcelFixture2) o;
142        return Arrays.equals(getBytes(), that.getBytes());
143    }
144
145    @Override
146    public int hashCode() {
147        return Arrays.hashCode(getBytes());
148    }
149
150    /**
151     * Input, optional: defines the name of the resource.
152     */
153    @java.lang.SuppressWarnings("all")
154    public String getExcelResourceName() {
155        return this.excelResourceName;
156    }
157
158    /**
159     * Input, optional: defines the name of the resource.
160     */
161    @java.lang.SuppressWarnings("all")
162    public void setExcelResourceName(final String excelResourceName) {
163        this.excelResourceName = excelResourceName;
164    }
165
166    /**
167     * Input, either this or the blob is mandatory ... the Excel spreadsheet to read.
168     */
169    @java.lang.SuppressWarnings("all")
170    public URL getExcelResource() {
171        return this.excelResource;
172    }
173
174    /**
175     * Input, either this or the blob is mandatory ... the Excel spreadsheet to read.
176     */
177    @java.lang.SuppressWarnings("all")
178    public void setExcelResource(final URL excelResource) {
179        this.excelResource = excelResource;
180    }
181
182    /**
183     * Input, either this or the excelResource is mandatory ... the Excel spreadsheet to read.
184     */
185    @java.lang.SuppressWarnings("all")
186    public Blob getBlob() {
187        return this.blob;
188    }
189
190    /**
191     * Input, either this or the excelResource is mandatory ... the Excel spreadsheet to read.
192     */
193    @java.lang.SuppressWarnings("all")
194    public void setBlob(final Blob blob) {
195        this.blob = blob;
196    }
197
198    /**
199     * Input, mandatory ... how to process each sheet of the workbook.
200     */
201    @java.lang.SuppressWarnings("all")
202    public WorksheetSpec.Matcher getMatcher() {
203        return this.matcher;
204    }
205
206    /**
207     * Input, mandatory ... how to process each sheet of the workbook.
208     */
209    @java.lang.SuppressWarnings("all")
210    public void setMatcher(final WorksheetSpec.Matcher matcher) {
211        this.matcher = matcher;
212    }
213
214    /**
215     * Input, optional ... which sequence to process the matched sheets
216     */
217    @java.lang.SuppressWarnings("all")
218    public WorksheetSpec.Sequencer getSequencer() {
219        return this.sequencer;
220    }
221
222    /**
223     * Input, optional ... which sequence to process the matched sheets
224     */
225    @java.lang.SuppressWarnings("all")
226    public void setSequencer(final WorksheetSpec.Sequencer sequencer) {
227        this.sequencer = sequencer;
228    }
229
230    /**
231     * Output... a list of list of objects (each representing a row of a sheet)
232     */
233    @java.lang.SuppressWarnings("all")
234    public List<List<?>> getLists() {
235        return this.lists;
236    }
237}