<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id$ */

package org.apache.fop.render.afp;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Collections;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.render.afp.modca.AbstractNamedAFPObject;
import org.apache.fop.render.afp.modca.DataObjectFactory;
import org.apache.fop.render.afp.modca.Registry;

/**
 * Caches and creates (as necessary using an instance of DataObjectFactory)
 * descendants of AbstractDataObject
 */
public final class DataObjectCache {

    /** Static logging instance */
    private static final Log log = LogFactory.getLog(DataObjectCache.class);

    private static final String CACHE_FILENAME_PREFIX = "AFP_";

    /** Static mapping of data object caches id --> cache */
    private static Map/*<Integer,DataObjectCache>*/ cacheMap
        = new java.util.HashMap/*<Integer,DataObjectCache>*/();    
    
    
    /** Mapping of data object uri --> cache record */
    private Map/*<ResourceInfo,Record>*/ includableMap
        = new java.util.HashMap/*<ResourceInfo,Record>*/();
    
    /** Used for create data objects */
    private DataObjectFactory factory = new DataObjectFactory();

    /** Used for storage of data objects */
    private RandomAccessFile raFile;
    
    /** File channel used for manipulating the temporary file */
    private FileChannel channel;
    
    /** The temporary cache file */
    private File tempFile;
    
    /** The next file pointer position in the cache file */
    private long nextPos;

    /** Our assigned cache id */
    private Integer id;
    
    /**
     * Returns an instance of the cache
     * 
     * @return an instance of the cache or null if failed
     */
    public static DataObjectCache getInstance() {
        synchronized (cacheMap) {
            Integer cacheId = new Integer(System.identityHashCode(Thread.currentThread()));
            DataObjectCache cache = (DataObjectCache)cacheMap.get(cacheId);
            if (cache == null) {
                try {
                    cache = new DataObjectCache(cacheId);
                    cacheMap.put(cacheId, cache);
                } catch (IOException e) {
                    log.error("Failed to create cache");
                }
            }
            return cache;
        }
    }

    /**
     * Default constructor
     * 
     * @param cacheId the cache id
     */
    private DataObjectCache(Integer cacheId) throws IOException {
        this.id = cacheId;
        this.tempFile = File.createTempFile(CACHE_FILENAME_PREFIX + cacheId, null);
        this.raFile = new RandomAccessFile(tempFile, "rw");
        this.channel = raFile.getChannel();
    }

    /**
     * Clears the data object cache
     */
    public void clear() {
        try {
            raFile.close();
            tempFile.delete();
            synchronized (cacheMap) {
                cacheMap.remove(id); // remove ourselves from the cache map
            }
        } catch (IOException e) {
            log.error("Failed to close temporary file");
        }
    }

    /**
     * Stores a named data object in the cache
     * 
     * @param dataObj a named data object
     * @return a new cache record
     */
    public Record store(AbstractNamedAFPObject dataObj) {
        Record record = new Record();
        record.objectName = dataObj.getName();
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            channel.position(nextPos);
            record.position = channel.position();<commit_msg>Better to remove on finally rather than the try block.<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id$ */

package org.apache.fop.render.afp;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Collections;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.render.afp.modca.AbstractNamedAFPObject;
import org.apache.fop.render.afp.modca.DataObjectFactory;
import org.apache.fop.render.afp.modca.Registry;

/**
 * Caches and creates (as necessary using an instance of DataObjectFactory)
 * descendants of AbstractDataObject
 */
public final class DataObjectCache {

    /** Static logging instance */
    private static final Log log = LogFactory.getLog(DataObjectCache.class);

    private static final String CACHE_FILENAME_PREFIX = "AFP_";

    /** Static mapping of data object caches id --> cache */
    private static Map/*<Integer,DataObjectCache>*/ cacheMap
        = new java.util.HashMap/*<Integer,DataObjectCache>*/();    
    
    
    /** Mapping of data object uri --> cache record */
    private Map/*<ResourceInfo,Record>*/ includableMap
        = new java.util.HashMap/*<ResourceInfo,Record>*/();
    
    /** Used for create data objects */
    private DataObjectFactory factory = new DataObjectFactory();

    /** Used for storage of data objects */
    private RandomAccessFile raFile;
    
    /** File channel used for manipulating the temporary file */
    private FileChannel channel;
    
    /** The temporary cache file */
    private File tempFile;
    
    /** The next file pointer position in the cache file */
    private long nextPos;

    /** Our assigned cache id */
    private Integer id;
    
    /**
     * Returns an instance of the cache
     * 
     * @return an instance of the cache or null if failed
     */
    public static DataObjectCache getInstance() {
        synchronized (cacheMap) {
            Integer cacheId = new Integer(System.identityHashCode(Thread.currentThread()));
            DataObjectCache cache = (DataObjectCache)cacheMap.get(cacheId);
            if (cache == null) {
                try {
                    cache = new DataObjectCache(cacheId);
                    cacheMap.put(cacheId, cache);
                } catch (IOException e) {
                    log.error("Failed to create cache");
                }
            }
            return cache;
        }
    }

    /**
     * Default constructor
     * 
     * @param cacheId the cache id
     */
    private DataObjectCache(Integer cacheId) throws IOException {
        this.id = cacheId;
        this.tempFile = File.createTempFile(CACHE_FILENAME_PREFIX + cacheId, null);
        this.raFile = new RandomAccessFile(tempFile, "rw");
        this.channel = raFile.getChannel();
    }

    /**
     * Clears the data object cache
     */
    public void clear() {
        try {
            raFile.close();
            tempFile.delete();
        } catch (IOException e) {
            log.error("Failed to close temporary file");
        } finally {
            synchronized (cacheMap) {
                cacheMap.remove(id); // remove ourselves from the cache map
            }
        }
    }

    /**
     * Stores a named data object in the cache
     * 
     * @param dataObj a named data object
     * @return a new cache record
     */
    public Record store(AbstractNamedAFPObject dataObj) {
        Record record = new Record();
        record.objectName = dataObj.getName();
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            channel.position(nextPos);
            record.position = channel.position();
{'fraction_non_alphanumeric': 0.09124767225325885, 'fraction_numerical': 0.000876328184905247, 'mean_word_length': 2.5061443932411676, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4736652', 'n_tokens_mistral': 2372, 'n_tokens_neox': 2320, 'n_words': 793}