001/* 002 * BridJ - Dynamic and blazing-fast native interop for Java. 003 * http://bridj.googlecode.com/ 004 * 005 * Copyright (c) 2010-2013, Olivier Chafik (http://ochafik.com/) 006 * All rights reserved. 007 * 008 * Redistribution and use in source and binary forms, with or without 009 * modification, are permitted provided that the following conditions are met: 010 * 011 * * Redistributions of source code must retain the above copyright 012 * notice, this list of conditions and the following disclaimer. 013 * * Redistributions in binary form must reproduce the above copyright 014 * notice, this list of conditions and the following disclaimer in the 015 * documentation and/or other materials provided with the distribution. 016 * * Neither the name of Olivier Chafik nor the 017 * names of its contributors may be used to endorse or promote products 018 * derived from this software without specific prior written permission. 019 * 020 * THIS SOFTWARE IS PROVIDED BY OLIVIER CHAFIK AND CONTRIBUTORS ``AS IS'' AND ANY 021 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 022 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 023 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 024 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 025 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 026 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 027 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 028 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 029 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 030 */ 031package org.bridj; 032 033import java.util.List; 034import java.util.concurrent.ConcurrentHashMap; 035import org.bridj.ann.Struct; 036 037/** 038 * Interface for type customizers that can be used to perform platform-specific 039 * type adjustments or other hacks.<br> 040 * A type customizer can be specified with {@link Struct#customizer() }.<br> 041 * Each implementation must have a default constructor, and an unique instance 042 * of each implementation class will be cached by {@link StructCustomizer#getInstance(java.lang.Class) 043 * }. 044 * 045 * @deprecated The StructIO API is subject to future changes. Use this with care 046 * and be prepared to migrate your code... 047 */ 048@Deprecated 049public class StructCustomizer { 050 051 /** 052 * Last chance to remove field declarations 053 */ 054 public void beforeAggregation(StructDescription desc, List<StructFieldDeclaration> fieldDecls) { 055 } 056 057 /** 058 * Last chance to remove aggregated fields 059 */ 060 public void beforeLayout(StructDescription desc, List<StructFieldDescription> aggregatedFields) { 061 } 062 063 /** 064 * This method can alter the aggregated fields and may even call again the 065 * performLayout(aggregatedFields) method. This is before field offsets and 066 * sizes are propagated to field declarations. 067 */ 068 public void afterLayout(StructDescription desc, List<StructFieldDescription> aggregatedFields) { 069 } 070 071 /** 072 * Called after everything is setup in the StructIO.<br> 073 * It is the most dangerous callback, here it's advised to only call the 074 * prependBytes, appendBytes and setFieldOffset methods. 075 */ 076 public void afterBuild(StructDescription desc) { 077 } 078 private static StructCustomizer dummyCustomizer = new StructCustomizer(); 079 private static ConcurrentHashMap<Class, StructCustomizer> customizers = new ConcurrentHashMap<Class, StructCustomizer>(); 080 081 static StructCustomizer getInstance(Class<?> structClass) { 082 StructCustomizer c = customizers.get(structClass); 083 if (c == null) { 084 Struct s = structClass.getAnnotation(Struct.class); 085 if (s != null) { 086 Class<? extends StructCustomizer> customizerClass = s.customizer(); 087 if (customizerClass != null && customizerClass != StructCustomizer.class) { 088 try { 089 c = customizerClass.newInstance(); 090 } catch (Throwable th) { 091 throw new RuntimeException("Failed to create customizer of class " + customizerClass.getName() + " for struct class " + structClass.getName() + " : " + th, th); 092 } 093 } 094 } 095 if (c == null) { 096 c = dummyCustomizer; 097 } 098 StructCustomizer existingConcurrentCustomizer = 099 customizers.putIfAbsent(structClass, c); 100 if (existingConcurrentCustomizer != null) { 101 return existingConcurrentCustomizer; 102 } 103 } 104 return c; 105 } 106}